【问题标题】:passing string from C++ to C# using void pointer使用 void 指针将字符串从 C++ 传递到 C#
【发布时间】: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^ 作为参数?还是作为返回值更好?为什么它甚至被用作非托管导入?

标签: c# c++ string dll


【解决方案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

【讨论】:

    猜你喜欢
    • 2014-11-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2019-12-13
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多