Search code examples
c#.netcinteroppinvoke

Automatically creating C# wrappers from c headers?


Is there a way to automatically create p/invoke wrappers for .net from a c header?

Of course I could create them by hand, but maintaining them would be painful, and I'd probably make a mistake somewhere resulting in hard to debug crashes.

I tried SWIG, but it created full classes where simple structs would be sufficient. Another problem with SWIG is that it requires additional interop code on the c side.

I'd prefer if the output worked on mono too, but that is not necessary.

Another thing I could work with is a program which parses the c header, and creates an output in a nice intermediate format like xml, from which I can create the C# wrapper myself.

Edit:
PInvoke Interop Assistant is what I needed.
There are some small issues with it though:
* It translates "unsigned char*" to string where I'd prefer IntPtr
* It assumes that size_t=int=long=32bit. This is currently true for me, but might not true on every platform.
Is there a clean way to fix that? Else I'll use a bit of find and replace on the c code before converting it.


Solution

  • The PInvoke Interop Assistant ought to be a better fit for you, it was specifically designed to work with C code.

    Just beware that no tool gives you a 100% guaranteed solution, C declarations are way too ambiguous to guarantee a completely trouble-free result. Trouble caused by pointers, ubiquitous in C code. There's no way to tell that a pointer is used to read or write memory. Or both. Or who is responsible for releasing the memory that is being pointed-to.

    This is a major hangup for static code analyzers as well, they can't do a decent job if they don't know how a pointer is used. They can only infer it from usage, but that's a chicken-and-egg problem, the usage might be wrong. Microsoft addressed the problem in their own headers with SAL annotations, extra markup that's neutral to a compiler but can be parsed by a code analyzer. They explicitly state the intended use a pointer.

    Also used by the Pinvoke Interop Assistant which is why it can do a better job on winapi declarations. But that of course only works on Microsoft headers, these SAL annotations are normally missing on code written by a busy C programmer.