【问题标题】:How to marshal a variable sized array of structs? C# and C++ interop help如何编组可变大小的结构数组? C# 和 C++ 互操作帮助
【发布时间】:2017-02-18 00:23:34
【问题描述】:

我有以下 C++ 结构

struct InnerStruct
{
   int A;
   int B;
};

struct OuterStruct
{
   int numberStructs;
   InnerStruct* innerStructs;
};

还有一个 C++ 函数

OuterStruct getStructs();

如何将其编组为 C#? C# 定义在哪里

struct OuterStruct {
   InnerStruct[] innerStructs;
};

【问题讨论】:

    标签: c# .net interop pinvoke marshalling


    【解决方案1】:

    您必须手动执行此操作,因为无法告诉 P/Invoke 层从您的 C++ 返回值中编组多少数据。

    struct OuterStruct {
       int numberStructs;
       IntPtr innerStructs;
    };
    
    OuterStruct s = getStructs(); // using DllImport
    var structSize = Marshal.SizeOf(typeof(InnerStruct));
    var innerStructs = new List<InnerStruct>();
    var ptr = s.innerStructs;
    
    for (int i = 0; i < s.numberStructs; i++)
    {
        innerStructs.Add((InnerStruct)Marshal.PtrToStructure(ptr, 
            typeof(InnerStruct));
        ptr = ptr + structSize;
    }
    

    请注意,如果您想从 C# 代码中释放 innerStructs 的内存,则必须在 C++ 代码中使用标准分配器 CoTaskMemAlloc——然后您可以调用 Marshal.CoTaskMemFree 来释放 innerStructs

    【讨论】:

    • 帅哥,非常感谢。另外,作为一个简单的问题,是否可以编组一个向量,这样我就可以让 OuterStruct 有一个 InnerStructs 的向量?我知道你不能编组类,但我想也许有人写了一些棘手的东西来做到这一点。
    • 我不知道,但我从未看过。 :-)
    • 你把指针指向int?如果它在 64 位进程中运行怎么办?! You don't need the casts
    • 请注意,在这种情况下将IntPtr 转换为int 是非常糟糕的主意。请不要!
    • @doug65536 是的,哎呀!固定的! (8 年后)
    猜你喜欢
    • 2011-08-19
    • 2010-12-03
    • 1970-01-01
    • 2017-09-27
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    相关资源
    最近更新 更多