首页 > 解决方案 > 将 Unicode 字符串从 C# 发送到 C++,在一个项目中工作,而不是在另一个项目中

问题描述

我在 VS2017 中构建了一个包含两个项目的测试工具解决方案,一个是我发送 unicode 字符串的 C# 项目,一个是我接收它并在 MessageBox 中显示的 C++ DLL。

我的 C# 代码是:

[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 ☻我是美国人");
    }

我的 C++ 代码是:

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

这可以按预期工作,输出如下:

在此处输入图像描述

伟大的。因此,我将代码移植到一个更大的解决方案中,再次使用与描述相同的小型 C# 测试项目,以及一个更大的现有 C++ 项目,其中我需要包含相同的字符串传递功能。

这次我的 C# 代码非常相似:

  [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 ☻我是美国人");
    }

和 C++ 代码也基本相同。

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

然而我得到了这个:

在此处输入图像描述

为了测试,我将 C++ 项目从 DLL 更改为 exe,并在本地调用 ProcessOneFile 函数,在同一 C++ 文件中使用 main() 中的以下代码:

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

我得到:

在此处输入图像描述

因此,数据似乎无法在从 C# 到 C++ 的边界传输中幸存下来。

两种解决方案都在同一台 PC 上运行,都在同一个 Visual Studio (2017) 中编译,这两个 c++ 项目都将属性 -> 常规 -> 字符集设置为“使用 Unicode 字符集”。

一定有一些与项目相关的东西导致了这种情况,任何帮助都将不胜感激。我根本不是 C++ 人,我试图从 Github 上的代码中获取我需要的功能。

感谢您的任何建议。

标签: c#c++dllunicodepinvoke

解决方案


首先停止cv::Mat从你的函数返回。导出 aclass从来都不是可取的。此外,OpenCV cv::Mat没有被导出。

此外,为避免名称混淆,请在函数定义前加上extern "C"

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


推荐阅读