使用void指针将字符串从C ++传递给C#

时间:2013-11-20 10:22:55

标签: c# c++ string dll

我正在使用这样的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);

我尝试过编组和其他各种建议,但我无法理解为什么我会得到垃圾值。这很简单,但我错过了什么。

1 个答案:

答案 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.AnsiMarshal::StringToXYZ,查看其他System::String函数,我会创建临时来自strcpy的字符串,然后我char*到目标缓冲区(检查带有{{1}}版本的Ansi后缀的函数)。有关此示例,请参阅this post here on SO