[英]C++ DLL LPCTSTR to C# string
I am trying to get string from C++ DLL to C#. 我试图从C ++ DLL到C#获取字符串。 It outputs incorrect symbols - {栠搂珯獲긋ݳݳ贈琹玴ɡݳ⻜}
它输出不正确的符号 - {栠搂珯获긋ݳݳ赠琹玴ɡݳݳ}
Here is my code: C++ DLL 这是我的代码:C ++ DLL
_declspec(dllexport) int __stdcall myClass(LPCTSTR& z)
{
z = _T("Test String");
return 0;
}
My C# code reading C++ DLL: 我的C#代码读取C ++ DLL:
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern void myClass(StringBuilder z);
static void Main(string[] args)
{
StringBuilder z = new StringBuilder();
myClass(z);
}
First, make sure you defined the UNICODE
macro in C++, so that _T
outputs wchar_t
data, and LPCTSTR
means const wchar_t*
. 首先,确保在C ++中定义了
UNICODE
宏,以便_T
输出wchar_t
数据, LPCTSTR
表示const wchar_t*
。 That's what CharSet.Unicode
expects. 这就是
CharSet.Unicode
期望的。 By the way, if you don't intend to support an ANSI version too, I wouldn't bother with all this _T
stuff and just use Unicode everywhere, the code will be simpler. 顺便说一句,如果你不打算也支持ANSI版本,我不会打扰所有这些
_T
东西,只是到处使用Unicode,代码会更简单。
Also, your C++ function returns an int
, but your C# function expects a void
. 此外,您的C ++函数返回一个
int
,但您的C#函数需要一个void
。 You have a mismatch there (unless you intended to set PreserveSig
to false
). 你有不匹配(除非你打算将
PreserveSig
设置为false
)。
On the C# side, when you provide a StringBuilder
, it means you provide a buffer to the C++ side, and you expect it to fill that buffer. 在C#方面,当你提供一个
StringBuilder
,它意味着你向C ++端提供一个缓冲区,并且你希望它填充该缓冲区。 The correct usage would be something like this: 正确的用法是这样的:
_declspec(dllexport) int __stdcall myClass(LPCTSTR z, int zSize)
{
_tcscpy_s(z, zSize, _T("Test String"));
return 0;
}
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(StringBuilder z, int zSize);
static void Main(string[] args)
{
StringBuilder z = new StringBuilder(256);
myClass(z, z.Capacity);
}
But your code returns a pointer to a static string, which the marshaller doesn't expect here. 但是你的代码返回一个指向静态字符串的指针,这是marshaller在这里不期望的。
If you'd like to keep your C++ code as-is, you could try this instead: 如果你想保持你的C ++代码,你可以尝试这样做:
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(out string z);
static void Main(string[] args)
{
string z;
myClass(out z);
}
I admit I didn't test it, but it should work as this C# signature matches the C++ signature. 我承认我没有测试它,但它应该工作,因为这个C#签名匹配C ++签名。
If everything fails, you could try to marshal the data by yourself: 如果一切都失败了,您可以尝试自己编组数据:
[DllImport("ecrClassDll.dll")]
static extern unsafe int myClass(void** z);
static unsafe void Main(string[] args)
{
void* z;
myClass(&z);
var str = Marshal.PtrToStringUni(new IntPtr(z));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.