Partager via


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[]. 

  1. 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.
  2. IntPtr is the lowest-common-denominator because you can always get the address of managed object as an IntPtr via GCHandle.AddrOfPinnedObject.
  3. 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:

  1. Importing the structure may be painful.
  2. If managed code just passes the native structure back to native methods without actually inspecting the structure, then importing it is unnecessary.
  3. 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.com

  • Anonymous
    November 30, 2006
    Lots of great stuff this time. CLR/Interop There has always been a ton of confusion about CLR assembly

  • Anonymous
    December 03, 2006
    Message de la part de Mike Stall : Marshal opaque structs as IntPtr instead of Byte[] Logique quand on

  • Anonymous
    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/#S8

  • Anonymous
    October 20, 2007
    Lots of great stuff this time. CLR/Interop There has always been a ton of confusion about CLR assembly

  • Anonymous
    July 22, 2008
    Lipitor and muscle pain. Side effects of lipitor drugs. Lipitor.

  • Anonymous
    December 03, 2008
    The comment has been removed