views:

301

answers:

2

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.

+1  A: 

If I understand your question correctly, you're basically asking if there is a way to do what SWIG does.

Of course, you want to do it a bit differently, so one option would be to take the SWIG code and change it to work the way you'd like.

John Fisher
+4  A: 

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. The trouble is 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.

Hans Passant
I agree with the Interop Assistant. Be aware though that the GUI has an annoying bug (limited length, annoying if you want to translate a lot of header files) and the generated C# code for bitfields is not only really ugly, but also wrong (i.e. you *must* verify the bit field code manually). For anything except bit fields, I found it to work fine, though the first thing I do with the code is to remove the lengthy namespaces (`System.Runtime.InteropServices` for each and every attribute).
OregonGhost
There are some small issues with it.It translates "unsigned char*" to string where I'd prefer IntPtr, and assumes that int=long=32bit. 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.
Winner
Those are the ambiguities I warned you about. No clean way, having to tinker the generated P/Invoke declaration is normal. Btw: int and long is 32-bits in most C/C++ code.
Hans Passant
Obviously c headers are ambiguous. This is why I hoped I could create a file influencing the code conversion and overriding some type mappings.But search and replace should be enough for my current problem.One interesting feature of the Interop Assistant is that it can create an xml file which might be useful in advanced cases.
Winner