从C#中调用一个wstring C++方法

本文关键字:一个 wstring C++ 方法 调用 | 更新日期: 2023-09-27 18:27:29

我正在使用C#代码,需要在C++dll中调用此方法。

static std::wstring DecryptData(const std::wstring& strKey);

我读过很多东西,我最好的猜测是传递一些对两种语言都更容易阅读的东西,比如char数组甚至字节数组,然后用C++构建wstring,用C#构建字符串。

有人已经这么做了吗?

编辑:

我阅读了链接主题,但没有一个答案对我有帮助:使用const没有帮助。

这就是我现在所拥有的:C#

 [DllImport(DLL_PATH, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.LPWStr)]
        public static extern string DecryptData([MarshalAs(UnmanagedType.LPWStr)]string strKey);

C++

extern "C" __declspec(dllexport) const std::wstring DecryptData(const std::wstring& strKey) {
    return WlanHelper::CWirelessHelper::DecryptData(strKey);
}

这给了我一个PInvokeStackImbalance=/

从C#中调用一个wstring C++方法

您可能会发现这个问题和这个问题是相关的。有两个问题:

  1. P/Invoke不以本机方式封送std::string/std::wstring,并且
  2. 可能存在内存寿命问题(取决于CWirelessHelper::DecryptData的实现)

一种方法是将字符串复制到使用CoTaskMemAlloc分配的普通wchar_t*缓冲区(框架将处理字符串转换并释放分配的内存)。

在非托管端,代码变为:

extern "C" __declspec(dllexport) const wchar_t* DecryptData( wchar_t* strKey) {
    std::wstring retstr = WlanHelper::CWirelessHelper::DecryptData(std::wstring(strKey));
    const wchar_t* ret = retstr.c_str();
    size_t bufsize = wcslen(ret) + 1;
    wchar_t* buffer = (wchar_t*)CoTaskMemAlloc(bufsize * sizeof(wchar_t));
    wcscpy_s(buffer, bufsize, ret);
    return buffer;
}

在管理方面:

[DllImport(DLL_PATH, 
    CharSet = CharSet.Unicode, 
    CallingConvention = CallingConvention.Cdecl)]
static extern string DecryptData(string strKey);