【问题标题】:How to create a VB.NET unmanaged structure which contains an array of structures?如何创建包含结构数组的 VB.NET 非托管结构?
【发布时间】:2018-09-29 02:11:49
【问题描述】:

我正在尝试调用一个 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 兼容的外部结构?

【问题讨论】:

  • Dim s As Outer 根本不创建(实例化)任何东西。它只是声明s 的类型为OuterNew 关键字/运算符创建一个 new 对象/结构。
  • 也许你只是初始化它? s.ArrayOfInners = New Inner(20) {}
  • 我尝试Dim s As New Outer 得到相同的结果(顺便说一句,Outer 的所有其他成员 都正确分配,没有“New”)。我认为 ArrayOfInners 会像 Outer 的其他成员一样自动分配,因为我声明了 &lt;StructLayout(LayoutKind.Sequential)&gt;
  • 所有字段都被初始化为其默认值,因为这就是 structs 的工作方式。与StructLayout 属性无关。引用类型的默认值为Nothing
  • 没有像Inners 数组这样的东西,它 VB.NET 中Outer 结构的连续部分;数组始终是引用类型。这就是编组步骤的用途——它根据调用时的属性将 .NET 值转换为预期的形式。

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


【解决方案1】:

如果其他人遇到这个问题,这里是解决方案(感谢用户 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

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

【讨论】:

    猜你喜欢
    • 2015-10-26
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    相关资源
    最近更新 更多