C++DLL LPCTSTR到C#字符串
本文关键字:字符串 LPCTSTR C++DLL | 更新日期: 2023-09-27 18:26:50
我正在尝试将字符串从C++DLL获取到C#。它输出不正确的符号-{栠搂珯獲긋ݳݳ贈琹玴ݳ⻜}
这是我的代码:C++DLL
_declspec(dllexport) int __stdcall myClass(LPCTSTR& z)
{
z = _T("Test String");
return 0;
}
我的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);
}
首先,确保您在C++中定义了UNICODE
宏,以便_T
输出wchar_t
数据,LPCTSTR
表示const wchar_t*
。这正是CharSet.Unicode
所期望的。顺便说一句,如果你不打算也支持ANSI版本,我就不会麻烦所有这些_T
的东西,只需要在任何地方使用Unicode,代码就会更简单。
此外,C++函数返回int
,但C#函数需要void
。您有一个不匹配(除非您打算将PreserveSig
设置为false
)。
在C#端,当您提供StringBuilder
时,这意味着您向C++端提供了一个缓冲区,并且您希望它填充该缓冲区。正确的用法是这样的:
_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);
}
但是您的代码返回一个指向静态字符串的指针,而整理器在这里并不期望这样。
如果你想保持你的C++代码原样,你可以试试这个:
[DllImport("ecrClassDll.dll", CharSet = CharSet.Unicode)]
static extern int myClass(out string z);
static void Main(string[] args)
{
string z;
myClass(out z);
}
我承认我没有测试它,但它应该可以工作,因为这个C#签名与C++签名匹配。
如果一切都失败了,你可以尝试自己整理数据:
[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));
}