Thursday, January 06, 2005

Dealing with the pain of C DLL interop

I had an email conversation with Dan last night and today about trying to get C# interop to a C DLL working. Dan's method call was succeeding, but the method wasn't doing what it was supposed to day. My final thoughts on the matter where:

The great problem with interop to C-style DLLs in that the fairly loose typing of C means that a parameter that is, say, char*, can mean a number of different things depending on what the method is documented as doing with the parameter. There is no way to automatically map parameter types. For char*, string, StringBuilder, and IntPtr could all be used.

My general strategy:

  • Find an API that has been mapped with a similar parameter and use that. The Windows API and Adam Nathan's conversions (Appendix E) of this is a good starting point.
  • Use the marshalling attributes where it makes sense, but don't kill yourself on them. Don't be ashamed to use Marshal.AllocHGlobal and do the marshalling by hand.
  • Watch out for byte-alignment padding.
  • Understand who is responsible for allocating memory and what heaps the memory is one.
  • Prefer manually allocated memory over pinned managed memory.
  • A Managed C++ wrapper is always much simpler than the C# or VB.NET equivalent.
  • A lot of Windows-centric interop can be replaced with WMI/ System.Management.
  • Get the OS and .NET Framework debug symbols.
  • Check the calling convention and character set.
  • Understand the basics of unmanaged debugging. It's not as hard as it might seem.


    Post a Comment

    << Home