如何编组包含指向未知类型的C样式数组的第一个元素的指针的结构

时间:2012-03-26 19:44:13

标签: c# .net pinvoke marshalling

我正在尝试从C ++到C#编组一个看起来像这样的结构:

typedef struct FooStruct {
    Uint8 bytesPerThingie;
    void *arrayOfThingies;
    // other members ...
}

所以,在这种情况下有两个未知数:

  1. 数组中的元素数。
  2. 每个元素的大小(以字节为单位)。
  3. 我之前已成功编组了结构本身,其定义如下:

    [StructLayout(LayoutKind.Sequential)]
    public struct FooStruct {
        public byte bytesPerThingie;
        public IntPtr arrayOfThingies;
        // other members...
    }
    

    但现在我需要检查和修改嵌入式数组。

    我理解

    1. 本身就是一个blittable类型的blittable元素数组 本身是blittable,但不是当它被用作a中的一个字段时 结构
    2. 从非托管代码封送到.NET Framework时,数组长度为 根据SizeConst参数确定,可选地后跟非托管类型 数组元素,如果它们不是blittable。
    3. 即使假设在这种情况下数组中的元素是blittable类型,如果在运行时之前我不知道数组的大小,我如何设置SizeConst,一个编译时参数?

1 个答案:

答案 0 :(得分:2)

长话短说,你不能。 SizeConst field上的MarshalAsAttribute class被编译为字段上的元数据,并且不能在运行时更改(至少,不会以对您有益的方式)。

那就是说,你有以下选择:

  • 您正在使用Marshal class上的方法手动编制内容。
  • 使用unsafe直接访问指针(并更改类型以使用指针)。这需要/unsafe compiler option,这可能是您的选择,也可能不是。
  • 使用C++/CLI在C ++中创建托管包装器,它将导出.NET类型,但在C ++中处理编组(这可能更容易,这取决于您的舒适程度和您尝试的API的复杂性访问)。

请注意,在上述情况的所有中,您仍然需要知道返回的数组的长度(它可能在结构中以及指针和类型)