Search code examples
c#c++dllunicodepinvoke

Sending Unicode string from C# to C++ working in one project but not another


I have built a test harness solution with two projects in VS2017, a C# project where I am sending a unicode string and a C++ DLL where I receive it and show it in a MessageBox.

My C# code is:

[DllImport(@"TestDLL.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private static extern void SendString([MarshalAs(UnmanagedType.LPWStr)] string str);

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        SendString("Test2 String ☻我是美国人");
    }

My C++ code is:

__declspec(dllexport) bool __stdcall SendString(wchar_t *IncomingPath)
{
    MessageBoxW(
        NULL,
        IncomingPath,
        L"Header",
        MB_ICONINFORMATION
    );
    return true;
}

This works as expected with output like this:

enter image description here

Great. So I transplanted the code into a larger solution, again with the same small C# test project as described, and a larger existing C++ project where I need to include the same string passing functionality.

This time my C# code is very similar:

  [DllImport(@"my.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private static extern void ProcessOneFile([MarshalAs(UnmanagedType.LPWStr)] string str);

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ProcessOneFile("Test2 String ☻我是美国人");
    }

and C++ code is basically the same too.

    __declspec(dllexport) cv::Mat __stdcall ProcessOneFile(wchar_t *FullFilePath) {
    MessageBoxW(
        NULL,
        FullFilePath ,
        L"Headervv",
        MB_ICONINFORMATION
    );
}

Yet I am getting this:

enter image description here

To test, I changed the C++ project from a DLL to an exe and called the ProcessOneFile function locally, using the following code from main() inside the same C++ file:

wchar_t *temp = L"C:/Z2C6BC1C克 - Copy.jpg";
ProcessOneFile(temp);

and I get :

enter image description here

So it seems the data is not surviving the transfer across the boundary from C# to C++.

Both solutions are running on the same PC, both compile in the same Visual Studio (2017) both c++ projects have Properties -> General -> Character Set set to "Use Unicode Character Set".

There must be something project related that is causing this, any help would be appreciated. I am not a C++ guy at all, I am trying to get the functionality I need from code on Github.

Thanks for any advice.


Solution

  • First stop returning the cv::Mat from your function. Exporting a class has never been advisable. Furthermore the OpenCV cv::Mat is not being exported.

    Also, to avoid name mangling prefix the function definition with extern "C":

    extern "C" __declspec(dllexport) void __stdcall ProcessOneFile(wchar_t *FullFilePath)