Search code examples
c#c++pinvokemarshalling

returning a LPTSTR from an unmanaged C++ DLL that contains '\0' characters


I have a C# gui calling an unmanaged C++ dll. callbacks are used for dll -> gui messaging.

in the dll a LPTSTR is created that may contain '\0' characters. that string needs to be passed back via a callback parameter to the gui, in full, via the callback.

unfortunately i can only get the string passed to the gui up until the null character. seems the marshaling cuts the string.

// C# callback declarations
public delegate bool callbackDelegate(int iEvent, [MarshalAs(UnmanagedType.LPWStr)] string SomeString);
private callbackDelegate callbackDelegateInstance;

// instantiating and calling the callback in C#
callbackDelegateInstance = new callbackDelegate(CallbackHandler);
DLLCallbackFunction(callbackDelegateInstance);

// C# callback handler
private bool CallbackHandler(int iEvent, [MarshalAs(UnmanagedType.LPWStr)] string SomeString)
{
    // SomeString only contains characters up until the null char
}

Is there a way to return the entire string, including null chars from the dll?

I do have access to dll and gui code.


Solution

  • You could marshal it as a raw byte array instead of an LPTSTR. If your data is not a constant size, you will have to add an additional length parameter.

    The delegate would be declared something like this:

     public delegate bool callbackDelegate(int iEvent, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] data, int dataCount);
    

    And on the unmanaged side:

    typedef void (__stdcall *callbackDelegate)(int iEvent, const char* data, int size);