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

时间:2018-04-18 18:14:21

标签: vb.net dll struct unmanaged typed-arrays

I'm trying to call a DLL function (written in C) that expects a pointer to an Outer structure, which in turn contains an array of Inner structures. The C structures look like this:

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

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

I defined the VB.NET structures as follows:

<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

However, when I instantiate an Outer and try to access the nested Inner array like this ...

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

... the VS editor complains Variable 'ArrayOfInners' is used before it has been assigned a value. A null reference exception could result at runtime. And indeed, at runtime I see that the value of s.ArrayOfInners is Nothing -- vs. what I expected: a nested array of Inner structures.

What's the problem here, and how can I instantiate an Outer structure that's compatible with the DLL?

1 个答案:

答案 0 :(得分:0)

如果有其他人遇到此问题,这是解决方案(感谢用户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函数,当函数返回时,VB会将所有结构的成员复制回s

除非首先明确创建ArrayOfInners,否则VB.NET无法执行这些分散/收集操作,因为Dim s As Outer仅将ArrayOfInners初始化为Nothing(实际上是NULL指针) ,并且无法将Nothing复制到DLL兼容的结构中。