You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建适配C DLL调用的VB.NET非托管结构体(含结构体数组)

在VB.NET中正确定义并调用含结构体数组的C DLL函数

我来帮你搞定这个跨语言调用的结构体问题!你已经正确定义了Inner结构体,接下来重点是把Outer结构体的定义补全,同时保证内存布局和C语言完全匹配,这样才能顺利调用DLL函数。

完整的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标注固定大小数组,SizeConst对应C里的数组长度20
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)>
    Public ArrayOfInners() As Inner
    ' C的unsigned char直接对应VB.NET的Byte类型
    Public b As Byte
End Structure

导入DLL中的目标函数

假设你的C DLL里的函数原型是这样的:

void ProcessOuter(Outer* pOuter);

那在VB.NET里可以这样声明导入:

<DllImport("你的DLL文件名.dll", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Sub ProcessOuter(ByRef outer As Outer)
End Sub

提示:如果你的DLL用的是stdcall调用约定(比如Windows系统API常用的),把CallingConvention.Cdecl改成CallingConvention.StdCall就行。

实际调用示例

现在你可以创建Outer实例、填充数据,然后调用DLL函数了:

' 初始化Outer实例
Dim myOuter As Outer
' 固定大小数组需要先初始化元素(索引0到19,共20个)
ReDim myOuter.ArrayOfInners(19)

' 给数组里的元素赋值
myOuter.ArrayOfInners(0).x = 100
myOuter.ArrayOfInners(0).y = 200
For i As Integer = 1 To 19
    myOuter.ArrayOfInners(i).x = i * 10
    myOuter.ArrayOfInners(i).y = i * 20
Next

' 设置b字段的值
myOuter.b = 1

' 调用DLL里的函数
ProcessOuter(myOuter)

关键注意事项

  • 必须保留StructLayout(LayoutKind.Sequential),这能保证VB.NET结构体的内存顺序和C语言完全一致,避免封送时出现内存错位。
  • 固定大小数组一定要用<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)>标注,不然CLR没法正确识别数组长度,大概率会触发内存访问错误。
  • 数据类型要严格对应:C的int对应VB.NET的Integer,unsigned char对应Byte,绝对不能混用。

内容的提问来源于stack exchange,提问作者Lambtron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:48:36