I'm writing a wrapper for a DLL that manages an OCR device. 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 wrote this signature in C#
... it is almost functional:
[DllImport(aDll.dll, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Auto)]
static unsafe extern ulong aMethod(ref IntPtr firstParameter,
ref IntPtr secondParameter);
I do the invocation in this way:
aMethod(ref firstParameter, ref secondParameter);
Marshalling and unmarshalling related t开发者_C百科o the strings is done as here:
Marshal.PtrToStringAnsi(firstParameter)
Marshal.PtrToStringAnsi(secondParameter)
Obviously, this marshalling has been selected based on DLL's API conventions.
Now, the marshalling process has a problem. Suppose that the device has an input with this string "abcdefg". If I use the DLL from pure C++ code I get "abcdefg" as an output. But, if I use the C# signature I´ve wroted, the string loses its first character and looks like "bcdefg".
What´s going wrong? How can I fix the C# method?
Try changing the CharSet
to CharSet = CharSet.Ansi
Assuming those parameters are given to you from the application, why not simply use:
[DllImport(aDll.dll, CallingConvention = CallingConvention.Cdecl,
CharSet = CharSet.Auto)]
static unsafe extern uint aMethod(out string firstParameter,
out string secondParameter);
If you want them to go both ways, you could use a ref StringBuilder
with a pre-allocated size (you should also use this if the C function expects you to manage your own memory -- you didn't say).
精彩评论