使用 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)