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

本文关键字:第一个 数组 元素 指针 结构 样式 包含指 未知 类型 何封送 | 更新日期: 2023-09-27 18:29:07

我正试图将一个看起来像这样的结构从C++封送到C#:

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

因此,在这种情况下,有两个未知因素:

  1. 数组中的元素数
  2. 每个元素的大小(以字节为单位)

我之前已经成功地封送了结构本身,定义如下:

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

但现在我需要检查和修改嵌入式阵列。

我知道

  1. 就其本身而言,blitable类型的blitable元素数组是本身是可blitable的,但当它用作结构
  2. 从非托管代码封送至.NET Framework时,数组长度为由SizeConst参数确定,可选地后跟非托管类型数组元素的,如果它们不是可blitable的

即使假设在这种情况下数组中的元素是blitable类型,如果我在运行时之前无法知道数组的大小,我如何设置SizeConst,一个编译时参数?

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

长话短说,你做不到。MarshalAsAttribute类上的SizeConst字段被编译为字段上的元数据,并且不能在运行时进行更改(至少不能以有利于您的方式进行更改)。

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

  • 使用Marshal类上的方法手动封送内容
  • 使用unsafe直接访问指针(并将类型更改为使用指针)。这需要/unsafe编译器选项,该选项可能适合您,也可能不适合您
  • 使用C++/CLI在C++中创建一个托管包装器,该包装器将导出.NET类型,但在C++中处理封送处理(这可能更容易,具体取决于您的舒适级别和您尝试访问的API的复杂性)

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