如何创建包含结构数组的 VB.NET 非托管结构?

How to create a VB.NET unmanaged structure which contains an array of structures?

我正在尝试调用一个 DLL 函数(用 C 编写),它需要一个指向外部结构的指针,而该结构又包含一个内部结构数组。 C 结构如下所示:

typedef struct Inner {
    int x;
    int y;
} Inner;

typedef struct Outer {
    Inner ArrayOfInners[20];
    unsigned char b;
} Outer;

我定义了 VB.NET 结构如下:

<StructLayout(LayoutKind.Sequential)> _
Public Structure Inner
    Public x As Integer
    Public y As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
Public Structure Outer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> Public ArrayOfInners() As Inner
    Public b As Byte
End Structure

但是,当我实例化一个 Outer 并尝试像这样访问嵌套的 Inner 数组时...

Dim s As Outer
s.ArrayOfInners(2).x = 5

...VS 编辑器抱怨 变量 'ArrayOfInners' 在赋值之前被使用。空引用异常可能会在运行时产生。 事实上,在运行时我看到 s.ArrayOfInners 的值是 Nothing——与我的预期相反:内部结构的嵌套数组.

这里有什么问题,如何实例化与 DLL 兼容的外部结构?

万一其他人遇到这个问题,这里是解决方案(感谢用户 Ry):

Dim s As Outer
s.ArrayOfInners = New Inner(19) {}  ' Must manually create every array in structure!
s.ArrayOfInners(2).x = 5

显然有必要在 s 中显式创建每个数组,因为 .NET 结构 s 不是传递给 DLL 函数的内容。相反,当调用 DLL 函数时,VB 将自动为 DLL 兼容结构分配内存,然后复制所有 s 的成员(包括其引用的、非连续的 ArrayOfInners ) 到结构。该结构被传递给 DLL 函数,当函数 returns 时,VB 会将结构的所有成员复制回 s.

VB.NET 无法执行这些 scatter/gather 操作,除非首先显式创建 ArrayOfInners,因为 Dim s As Outer 仅将 ArrayOfInners 初始化为 Nothing (实际上是 NULL 指针),并且无法复制 Nothing to/from DLL 兼容结构。