Marshal opaque structs as IntPtr instead of Byte[]
If you have an opaque native structure that you want to pass through managed code, consider using IntPtr, not Byte[], in your marshalling signatures. Opaque means that you don't care about the contents of the buffer. For example, if in C#, you pinvoke to get an opaque native structure that you then hand to some other native API, the pinvoke definitions should use IntPtr instead of Byte[].
- IntPtr doesn't have extra copying. Byte[] lives on the GC heap and so the memory can be moved around. Thus you may need to copy from the unmanaged memory onto the GC heap (probably via Marsahl.Copy), and then back again.
- IntPtr is the lowest-common-denominator because you can always get the address of managed object as an IntPtr via GCHandle.AddrOfPinnedObject.
- IntPtr's aren't paying for extra functionality. If the opaque structure just comes into managed code and then gets passed back to native, then you don't need any functionality beyond an IntPtr.
Note I've been saying "opaque" native structure here, meaning that we just need the bytes to pass through managed code, but we don't need to actually look at them in managed code. That's in contrast to importing the native structure definition into managed code and then use normal marshalling techniques. This can work too, but may have some drawbacks:
- Importing the structure may be painful.
- If managed code just passes the native structure back to native methods without actually inspecting the structure, then importing it is unnecessary.
- If the structure is not cross-platform, you may need different managed definitions for each platform. This could make your managed become platform dependent.
Another alternative may be to use unsafe IL, like C#'s fixed keyword, and the address-of operator. But now you've got unsafe code.
On a related note, check out Josh William's comments on Byte[] vs. byref byte.
Comments
Anonymous
November 29, 2006
You've been kicked (a good thing) - Trackback from DotNetKicks.comAnonymous
November 30, 2006
Lots of great stuff this time. CLR/Interop There has always been a ton of confusion about CLR assemblyAnonymous
December 03, 2006
Message de la part de Mike Stall : Marshal opaque structs as IntPtr instead of Byte[] Logique quand onAnonymous
December 20, 2006
Native HANDLEs and HMODULEs are classic cases of opaque pointers which can be marshalled by use of IntPtr. I always use following MSDN articles by Jason Clark as quick reference guides for PInvokes - http://msdn.microsoft.com/msdnmag/issues/03/07/NET/#S8 http://msdn.microsoft.com/msdnmag/issues/03/07/NET/#S8Anonymous
October 20, 2007
Lots of great stuff this time. CLR/Interop There has always been a ton of confusion about CLR assemblyAnonymous
July 22, 2008
Lipitor and muscle pain. Side effects of lipitor drugs. Lipitor.Anonymous
December 03, 2008
The comment has been removed