Some notes on C# and P/Invoke

I’ve spent the afternoon (slowly) trying to wrap up enough of libbluetooth to be able to use a bluetooth HID from a C# library. I’m not too far along, but here’s just a few basic things I’ve noticed while doing the data marshaling.

  • C# 2.0 has a fixed keyword so you can define a struct containing a fixed size array to match that being done in a c struct. This is handy when your fixed size array is not at the end of the struct, in which case you could just set StructLayoutAttribute Size field to include the extra bytes necessary for your array. Before 2.0 the solution was to declare int arrayItem1; int arrayItem2; ... int arrayItemN; in the struct to pad out the structure size appropriately. That works, but is irritating for accessing the array without using pointer arithmetic. Using the fixed keyword lets you access the data as an array after sending it through Marhsal.PtrToStructure(), which is great. An annoying side effect of this is that the array has a null size attribute, so you can’t foreach() over it.
  • Marhsal.PtrToStructure() is pretty nice for getting a blob of unmanaged memory back into a usable structure. I’ve never really gone this far into using P/Invoke, and so I’m having to learn how to use the interop parts of the (.NET | Mono) framework and move control and data between managed and unmanaged code and memory. The routine seems to be allocate a buffer of unmanaged memory with Marhsal.AllocHGlobal(), P/Invoke to an unmanaged library, passing the buffer along as an IntPtr by ref, pull the data into a managed struct from the unmanaged buffer when it comes back with PtrToStructure(), then free the buffer with Marshal.FreeHGlobal().

I’ll probably run into more stuff that is a little tough for me to wrap my head around bouncing from managed land to unmanaged, but this is a pretty good start. :)