Stack-allocating wrapped C++ objects

In CxxWrap.jl, each C++ type has an associated type of the form:

type WrappedCxxType
  ptr::Ptr{Void} # Pointer to the C++ object
end

The reason for this is that the C++ object may be created using a constructor called from Julia, so it needs a finalizer associated with it. Unfortunately, this also means the wrapper is heap-allocated, even when it is returned for an already existing object and no finalizer is needed. So for performance reasons, I really want to make this an immutable, but then I see no way to delete an allocated object when needed (apart from manually calling a function). The performance problem comes up running a sparse matrix assembly loop for example, where the Julia loop is twice as slow as the C++ loop because of these allocations.

To alleviate this, I was thinking of the following construct:

# Used as the constructor return type
type AllocatedWrappedCxxType
  ptr::Ptr{Void} # Pointer to the C++ object
end

# Used as existing pointer and reference return type
immutable WrappedCxxTypeRef
  ptr::Ptr{Void} # Pointer to the C++ object
end

In addition to that, there would be a convert function to convert between both types and function signatures would take the union of these types as arguments. I’m hesitating to implement this, because it feels a bit complicated and I want to make sure I’m not missing a more obvious solution.

Also, what’s the progress on this:
https://github.com/JuliaLang/julia/pull/12205

Seems like it would be the perfect solution here.

You can certainly do this. It’ll just segfault if you don’t manage memory correctly since it won’t do that automatically anymore.

The stack allocation PR won’t handle this case.

This is somewhat off-topic, but I don’t think you can reasonably rely on the finalizer to delete the object. In my experience these objects tend to live in memory for a lot longer than you expect because the Julia GC doesn’t know how large they are.

Therefore I think you should prefer manually managing the memory or avoiding using Ptr{Void} as a field type. In my case I was able to do the latter, but I think I pay for it by doing extra copies when moving data between Julia and C++.

See for reference