【问题标题】:Passing an array of strings from C++ to C#将字符串数组从 C++ 传递到 C#
【发布时间】:2015-12-23 12:32:42
【问题描述】:

我已经编写了这段运行良好的代码:
C++ 代码

extern "C"
{
    const MYLIBRARY_EXPORT char* giefStrPlx(char* addon)
    {
        return addon;
    }
}

C# 代码

[DllImport("ClassLibrary1")]
private static extern IntPtr giefStrPlx(string x);

void Start()
{

    IntPtr stringPtr = giefStrPlx("Huntsman");
    string huntsman = Marshal.PtrToStringAnsi(echoedStringPtr);
}

在此huntsman 之后包含“猎人”。


我的问题是对字符串数组执行类似操作的步骤。我写了以下函数

extern "C"
{
    const MYLIBRARY_EXPORT bool fillStrArray(char** lizt, int* length)
    {
        char* one = "one";
        char* two = "two";
        char* three = "three";

        lizt[0] = one;
        lizt[1] = two;
        lizt[2] = three;

        *length = 3;
    }
}

然后我尝试用 C# 编写以下代码

[DllImport("ClassLibrary1")]
private static extern bool fillStrArray(ref IntPtr array, ref int length);

void Start()
{
    IntPtr charArray = IntPtr.Zero;
    int charArraySize = 0;
    fillStrArray(ref charArray, ref charArraySize);

    IntPtr[] results = new IntPtr[charArraySize];
    Marshal.Copy(charArray, results, 0, charArraySize);

    foreach (IntPtr ptr in results)
    {
        string str = Marshal.PtrToStringAnsi(ptr);
    }
}

这不起作用。所以现在我有点迷失了如何做到这一点。

【问题讨论】:

  • 您的 C 代码要求您传递一个指向内存的指针,它可以将字符串指针写入该内存。 IntPtr.Zero 不可写。您也不知道需要分配多少内存。使用 IntPtr charArray = Marshal.AllocHGlobal(crossMyFingers) 其中 crossMyFingers 是一个很大的数字,此代码需要至少 3 * IntPtr.Size 但应该更大以减少堆损坏的几率。您可以设置 length 参数来帮助它避免这种损坏。
  • 感谢您的指点。即使进行更改,我仍然遇到问题。我正在尝试将它与 Unity 一起使用,但插件会使其崩溃,这使得调试更加困难。我没有将指针传递给数组,而是返回了一个指针,这与我在第一个示例中所做的不同。

标签: c# c++ marshalling


【解决方案1】:

这是我从 CLR 到 std::string 以及从 std::string 到 string CLR 的两个辅助函数

std::string CLROperations::ClrStringToStdString(String^ str)
{
    if (String::IsNullOrEmpty(str))
        return "";

    std::string outStr;
    IntPtr ansiStr = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str); 
    outStr = (const char*)ansiStr.ToPointer(); 
    System::Runtime::InteropServices::Marshal::FreeHGlobal(ansiStr); 
    return outStr;
}

String ^ CLROperations::StdStringToClr(std::string str)
{
    return gcnew String(str.c_str());
}

要使用字符串列表,您需要使用List<String^>^ 注意大写字符串。对于 std::string 的列表,请使用 std::vector<std::string>

【讨论】:

  • 很抱歉,但我不明白这对我遇到的问题有何帮助。
  • 不要使用 IntPtr 和 char*。改用 std::string
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多