我希望有人能解释一下到底有什么区别:
在我的 C# 程序中,我想将一个字符串传递给 C++ 方法。 我的 C# 代码如下所示:
[DllImport("Test.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern String DoIt(String filename);
我的 C++ DLL 的内部如下所示:
__declspec(dllexport) CString DoIt(char* szFilename)
{
....
}
如果我传递字符串(例如:C:\temp\my.txt),它会变成格式错误 =>"Ôœ&°8é-"。
现在是我无法完全理解的令人困惑的部分。如果我将返回类型从 CString 更改为 char*,一切都很好。
__declspec( dllexport ) char* DoIt(char* filename)
为什么会这样? C# 中的 CharSet 已设置为 Ansi 以将字符串编码为正确的类型。我无法弄清楚返回类型和我传递的字符串之间的联系在哪里。
如果您需要更多信息,请告诉我。
最佳答案
您的代码的两个版本都是错误的。您当然不能将 CString
作为互操作类型传递。您使用简单类型进行互操作,而不是 C++ 类。
使用 char*
时的错误更微妙。在那种情况下,有两个问题。
首先,在 C# 端使用 string
返回类型,pinvoke marshaller 假定返回的字符串是用 CoTaskMemAlloc
分配的,并将调用 CoTaskMemFree
在它被复制后释放它。
其次,虽然我们看不到它,但您的 C++ 代码几乎肯定会返回指向 C++ 函数中局部变量所拥有的缓冲区的指针。显然,当函数返回时,这个局部变量超出了范围,因此指针变得无效。
一些选项:
- 让调用者找到字符串缓冲区并让被调用者填充它。
- 使用
CoTaskMemAlloc
分配返回的char*
以满足 C# 代码的预期。 - 使用 pinvoke 编码器理解的 COM
BSTR
类型。
关于c# - 将字符串从 C# 传递到 C++ DLL 不同返回类型上的不同文本编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52090742/