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

Posted

技术标签:

【中文标题】使用 void 指针将字符串从 C++ 传递到 C#【英文标题】:passing string from C++ to C# using void pointer 【发布时间】:2013-11-20 10:22:55 【问题描述】:

我有这样的 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);

我尝试了编组和其他各种建议,但我无法理解为什么我会得到垃圾值。它相当简单,但我缺少什么。

【问题讨论】:

“temp”的地址本身不是字符串,那么 memcpy 将无法按预期工作。 你为什么要这样做?为什么要在可以处理 .NET 类型的两种语言之间传递指针?如果您的 C++ 实际上是 C++/CLI,正如使用 String^ 所建议的那样,为什么不使用 String^ 作为参数?还是作为返回值更好?为什么它甚至被用作非托管导入? 【参考方案1】:

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* 版本的带有Ansi 后缀的函数)。有关示例,请参阅 this post here on SO。

【讨论】:

以上是关于使用 void 指针将字符串从 C++ 传递到 C#的主要内容,如果未能解决你的问题,请参考以下文章

通过 void 指针通过 C ABI 传递 C++ 对象(可能具有多重虚拟继承)

从 C++ 传递函数指针以由 C# 调用 - 函数参数包括宽字符字符串 (LPCWSTR)

如何在 C++ 中通过指针传递字符串?

将c ++引用的地址传递给指针

SWIG:将 Python 字符串传递给 void 指针类型的参数

C++ 通过引用传递向量字符指针