views:

66

answers:

2

I am attempting to use llvmc as a C# library using P/Invokes(because I can't find any .NET bindings).

However, I've a problem. llvmc uses char** for error passing.

An example would be this:

char* error = NULL;
LLVMVerifyModule(PointerToSomeModule, LLVMAbortProcessAction, &error);

What should I do to allow this function to be used in C# code?

EDIT: The example I found also mentions this call:

LLVMDisposeMessage(error);

I just saw the answers and thought this could be an important detail.

A: 

Take a look at the StringBuilder class. Or you can also simply declare the parameter as an integer out parameter and use Marshal.PtrToStringAnsi.

Jim Brissom
+5  A: 

A char** argument is troublesome, there is a memory management problem. If you declare the argument as "out string", the P/Invoke marshaller is going to try to free the pointer. That's very unlikely to work, it requires the string to be allocated with CoTaskMemAlloc().

The only other option you have to declare it as "out IntPtr" and marshal the string yourself with Marshal.PtrToStringAnsi(). That will work, beyond an unpluggable memory leak if LLVMC actually expects you to free the pointer. Call it a million times to verify that. There are a few odds that it won't blow since it is an error message, it might return a pointer to a string literal.

The only option left then is to write a wrapper in the C++/CLI language so you can free the pointer.

Hans Passant
Beat me to it. +1 for mentioning memory management.
Jim Brissom
What about P/Invoking malloc/calloc and free?
luiscubal
They are not exported.
Hans Passant
LLVMDisposeMessage(error) can be used (or so the example I saw says) to dispose the error message.
luiscubal
Whooptidoo, that's what you need. Declare the argument as IntPtr on both and use the manual marshaling I recommended.
Hans Passant