Search code examples
c#.netpinvokecharmarshalling

PInvoke and char**


I got this assembly from someone which I'd like to use in my c# application.

The header looks like this:

int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len);

I managed to get it partly working, using:

[DllImport("s2o.dll", EntryPoint = "?skn2obj@@YAHPA_WPAPADPAH@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int s2o(
    [MarshalAs(UnmanagedType.LPWStr)]
    string filename,
    ref char[] @out,
    ref int len
);

And then calling it like this:

char[] result = null;
int length = 0;
s2o("filepath", ref result, ref length);

It seems to work partly, because 'length' actually gets a value. Unfortunatly, 'result' stays null.

What should I do to get this working?

Edit:

Ok I managed to get to to work by replacing the char[] with a IntPtr and then calling 'Marshal.PtrToStringAnsi' like Nick suggested:

string result = Marshal.PtrToStringAnsi(ptr);

However, because of the comments in that same answer I'm a little worried about memory usage. There are no other methods provided in the assembly so how can I clear things up?


Solution

  • Have a look at the Marshal.PtrToStringAnsi Method.

    Or as Centro says in the comment to your question, PtrToStringAuto may be more appropriate.

    Copies all characters up to the first null character from an unmanaged ANSI string to a managed String, and widens each ANSI character to Unicode.

    Also note that you may be responsible for freeing the memory returned from this function.