【问题标题】:Call a wstring C++ method from C#从 C# 调用 wstring C++ 方法
【发布时间】:2016-03-26 05:05:58
【问题描述】:

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

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

我已经阅读了很多东西,我最好的猜测是传递两种语言都更容易阅读的东西,比如字符数组甚至字节数组,然后在 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 atm。
  • [DllImport("path.dll", CharSet=CharSet.Unicode)] static extern string DecryptData([MarshalAs(UnmanagedType.LPWStr)]string strKey); ?
  • @drf 最好把 DLL 添加为参考
  • 你可以选择更改c++函数吗?

标签: c# c++ wstring


【解决方案1】:

您可能会发现 this questionthis question 是相关的。有两个问题:

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

一种方法是将字符串复制到使用CoTaskMemAlloc (the framework will handle the string conversion and free the allocated memory) 分配的普通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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2015-06-29
    • 2012-02-09
    • 1970-01-01
    相关资源
    最近更新 更多