Search code examples
c#c++pinvoke

How do I convert from an unmanaged C++ dll char** to a C# string and back


I am trying to call a function on a unmanaged C++ DLL, searching stackoverflow posts I came up close but I cant get it to fully work.

With a declaration in the .h file as follows:

extern int SomeDLLMethod(const char **data, int *count);

the data is a string

I have declared in C# as follows:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int SomeDLLMethod(IntPtr data, ref int count);

Then i can call it from C# as follows:

unsafe
{
    fixed (byte* buffer = new byte[MAX_LENGTH])
    {
        IntPtr ptr = new IntPtr(buffer);
        int count = 0;
        var retVal = SomeDLLMethod(ptr, ref count);
        var dataString = Marshal.PtrToStringAuto(ptr);
        Console.WriteLine(dataString);
     }
 }

The call succeeds, there is a count and data in buffer, but how do I read this value back to C# string?

The Marshal methods is giving me garbage


Solution

  • There's not enough information in the question to be 100% sure but my guess is that you need this:

    [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern int SomeDLLMethod(ref IntPtr data, ref int count);
    .....
    IntPtr data;
    int count;
    int retval = SomeDLLMethod(ref data, ref count);
    string str = Marshal.PtrToStringAnsi(data, count);
    

    Ideally when asking a question like this you should include the full documentation of the native function. I say this because a char** can mean many different things.

    My assumption is that the char** here is a pointer to a null-terminated C string allocated by the DLL. Your code assumes that the caller allocates the buffer but if that were so then I would expect to see char* rather than char**.