How can I write a signature on C# for a wrapped C+

2019-09-14 02:10发布

I'm writing a wrapper for a dll. The dll has a method whose signature resembles the following:

unsigned long aMethod(char **firstParameter, char **secondParameter))

aMethod returns string pointers to all parameters.

I've searching at google for a tutorial to give me insight on how to write the signature on C# so the framework can do the marshalling process.

How can it be written? Do you know about any tutorial, book or documentation on this subject?

3条回答
女痞
2楼-- · 2019-09-14 02:36

I got the answer:

The signature has to be like this:

[DllImport(aDll.dll, CallingConvention = CallingConvention.Cdecl, 
    CharSet = CharSet.Auto)]
static unsafe extern ulong aMethod(ref IntPtr firstParameter, 
    ref IntPtr secondParameter);

Parameters should be declared as here:

IntPtr firstParameter = new IntPtr();
IntPtr secondParameter = new IntPtr();

And invocation is done as:

aMethod(ref firstParameter, ref secondParameter);

Marshalling and unmarshalling related to the strings as here:

Marshal.PtrToStringAnsi(firstParameter)
Marshal.PtrToStringAnsi(secondParameter)

Obviously, this marshalling has been selected based on dll´s API conventions.

I´m not sure after all, but all the problems had they source in the Charset and CallingConvention options...

查看更多
Animai°情兽
3楼-- · 2019-09-14 02:37

Not really answering you question but one tool that can help you if you have a lot of methods in a .dll that you want to call from C# is swig http://www.swig.org . It let's you generate a wrapper around the .dll from a interface file. One way to learn how to do it would be to study how swig does it.

查看更多
在下西门庆
4楼-- · 2019-09-14 02:45

Can't you just write it as

ulong aMethod(out IntPtr firstParameter, out IntPtr secondParameter);

To use it:

IntPtr p1;
IntPtr p2;

aMethod(out p1, out p2);

string p1Str = Marshal.PtrToStringAnsi(p1);
string p2Str = Marshal.PtrToStringAnsi(p2);

I'm assuming, of course, that you don't want to operate on the actual memory returned by that method. If you want to operate on the actual bytes, you can call Marshal.ReadByte, passing it the pointer that you received.

Note that if the called method is allocating memory for those strings before passing them to you, you have a memory leak unless you can call something in that API to free the memory.

Also note that if you're operating directly on the bytes, there's no guarantee that something else in the API won't pull the rug out from under you.

查看更多
登录 后发表回答