我正在使用这样的C ++代码,试图从c ++ dll获取C#应用程序的字符串。
int GetValue(void *pBuffer)
{
int x = 0;
String^ temp;
temp = "TestStringtest1test2";
memcpy(pBuffer, &temp,sizeof(temp));
Console::WriteLine(temp);
return x;
}
在c#方面,我所做的只是
[DllImport("Cplusplusapp.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern int GetValue(StringBuilder pBuffer);
StringBuilder Buffer = new StringBuilder(100);
int x = GetValue(Buffer);
Console.WriteLine(Buffer);
我尝试过编组和其他各种建议,但我无法理解为什么我会得到垃圾值。这很简单,但我错过了什么。
答案 0 :(得分:0)
temp
的地址不是字符串本身,然后memcpy
将无法按预期工作。此外,sizeof(String)
将返回System.String
对象的大小(32位机器上的4个字节),而不是字符串长度。
如果您需要将托管字符串中的值复制到非托管指针,则必须执行后续步骤。
首先System.String
始终是UNICODE,然后你不会有char*
而是wchar_t*
(但你可以将它转换为你需要的普通助手宏)。要将字符串从System.String
转换为wchar_t*
,请致电Marshal::StringToBSTR()
:
String^ temp = L"My string";
BSTR bstr = Marhshal::StringToBSTR(temp);
memcpy(pBuffer, bstr, SysStringLength(bstr));
Marshal::FreeBSTR(bstr);
当然,如果您不需要使用System.String
,则可以跳过所有这些,而不是将字符串分配给System.String
。根据您导入该功能的方式(wchar_t*
或更改char*
,将其更改为CharSet.Ansi
或Marshal::StringToXYZ
,查看其他System::String
函数,我会创建临时来自strcpy
的字符串,然后我char*
到目标缓冲区(检查带有{{1}}版本的Ansi后缀的函数)。有关此示例,请参阅this post here on SO。