Reputation: 1812
Is there any way to pass C# object references (class types, not structs) into and out of C++ via native interop?
Here's my use case:
I'm trying to write a game engine in C# but want to use a native (C++) physics library. The physics library maintains its own internal state of all the physical bodies and lets the user associate a small amount of data (a pointer) with each body. After a physics simulation tick, the library supplies a list of all physical bodies that moved. I want to iterate over this list and relay all the changes to the corresponding C# objects.
The question is: what's the best way to associate objects in C# with the corresponding physical bodies in C++?
I can think of a couple ways:
Is there any mechanism like option 3 I don't know of? C++/CLI isn't an option since I want to support platforms without it.
Upvotes: 5
Views: 5034
Reputation: 6738
Marshal.GetFunctionPointerForDelegate
to get an address to pass to the unmanaged side. The only thing to note is that you have to make sure that the callback is using __stdcall
.Also, remember that AccessViolationException
s are generally not catchable in .NET.
Upvotes: 2
Reputation: 6447
I would suggest using the tool that was specifically designed for situations like that, i.e. System.Runtime.InteropServices.GCHandle
.
Usage
In:
GCHandle
for your CLR object with GCHandleType.Normal
or GCHandleType.Weak
.GCHandle
to an IntPtr
via GCHandle.ToIntPtr
.IntPtr
to the C++ side as the userdata pointer that you mentioned.Out:
IntPtr
back from the C++ side.IntPtr
back to a GCHandle
via GCHandle.FromIntPtr
Target
Property of the GCHandle
to get to the original CLR object.When the CLR object is no longer being referenced from the C++ side (either because the C++ object was destroyed or because you reset the userdata pointer to e.g. IntPtr.Zero
), release the GCHandle
by calling GCHandle.Free
.
What type of GCHandle
you should allocate depends on whether you want the GCHandle
to keep the object alive (GCHandleType.Normal
) or not (GCHandleType.Weak
).
Upvotes: 8