Hello,
the method
public static GeometryBase CreateFromNativePointer(
IntPtr pGeometry
)
from the Rhino.Runtime.Interop class in Rhincommon takes a native pointer, generated by something like
ON_Mesh* m = new ON_Mesh(....);
in C++, and makes the object the garbage collector’s responsibility. This sounds extremely useful: one could just manufacture objects natively, and this would decrease the necessary amount for P/Invoking a lot. However, according to what I’ve read the .dotnet runtime might link to a different C++ runtime library than Rhino itself or the originating dll - such as a plugin’s dll -, and might therefore use a different heap. The garbage collector will eventually ask the runtime to call “delete” on the pointer, and that would lead to a crash if the “new” was done on another heap than the “delete”, see this Microsoft blog entry and many other discussions. So my question is: Has that method been tried out in a context where the GC finalizes and destroys that object, and has it proven safe?
It might be worth considering to have Rhinocommon wrap the pointer in a safe handle, so that the library can provide its own deallocation function.
The problem would be solved if new and delete were both done by opennurbs.dll - Rhino will load one and only one opennurbs.dll. Indeed, in the file opennurbs_memory.h of the Rhino 7 SDK it says:
/*
/////////////////////////////////////////////////////////////////////////////
//
// ALL memory managment in the openNURBS toolkit is done through calls to
// onmalloc(), oncalloc(), onrealloc(), onfree(),
// onmemdup(), onstrdup(), ..., and the
// new and delete operators
// The on*() functions are all declared in opennurbs_memory.h and defined
// in opennurbs_memory.c. The new and delete operators that use onmalloc()
// and onfree() are defined in opennurbs_plus_memory_new.cpp.
but there is no header opennurbs_plus_memory_new.h, and in the Rhino 8 SDK’s opennurbs_memory.h, that hint has disappeared! Does that mean Rhino 8 doesn’t have its own new/delete anymore?
TLDR: If a plugin developer does not have the necessary headers to make sure new/delete is consistent with Rhino/Grasshopper’s underlying new/delete, it seems very dangerous/impossible to pass memory ownership between the plugin and Rhino/Grasshopper using CreateFromNativePointer.
Cheers,
Mathias