VB.NET调用第三方C DLL时结构体数组封送异常问题排查
问题分析与解决方案
你的问题核心在于VB.NET中内嵌固定大小数组的声明方式错误,导致内存布局和C端结构体不匹配,进而使nPolygonNum之后的数据解析异常。以下是具体修正步骤:
1. 修正结构体的内存对齐(Pack值)
C语言中结构体默认按成员最大字节数对齐(这里int/long为4字节,默认Pack=4)。你给DH_RECT和DH_POINT设置Pack:=1会破坏对齐规则,导致内存偏移错误。需统一将所有结构体的Pack设为4,和C端保持一致:
<StructLayout(LayoutKind.Sequential, Pack:=4)> Public Structure DH_RECT Public left As Int32 Public top As Int32 Public right As Int32 Public bottom As Int32 End Structure <StructLayout(LayoutKind.Sequential, Pack:=4)> Public Structure DH_POINT Public nx As Int16 Public ny As Int16 End Structure
2. 修正内嵌数组的声明
C端的Contour[DH_MAX_POLYGON_NUM]是固定大小的内嵌数组,你用Contour() As DH_POINT声明的是动态数组,即便加上MarshalAs(ByValArray)也无法正确映射内存。正确做法是声明固定大小数组:
将Contour() As DH_POINT改为Contour(15) As DH_POINT(SizeConst:=16对应16个元素,VB数组索引从0开始,因此上限为15),同时保留MarshalAs属性:
<StructLayout(LayoutKind.Sequential, Pack:=4)> Public Structure DH_MSG_OBJECT Public nObjectID As Int32 <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)> Public szObjectType As String Public nConfidence As Int32 Public nAction As Int32 Public BoundingBox As DH_RECT Public Center As DH_POINT Public nPolygonNum As Int32 <MarshalAs(UnmanagedType.ByValArray, SizeConst:=16)> Public Contour(15) As DH_POINT ' 固定大小数组,对应C端16个元素 Public rgbaMainColor As UInt32 ' 其他成员... End Structure
3. 额外验证点
- 确认
DH_MAX_POLYGON_NUM的值确实为16,若实际值不同,需同步修改SizeConst和数组上限。 - 字符串部分:
UnmanagedType.ByValTStr自动适配系统ANSI编码,和C端char数组匹配,无需调整。 DWORD对应UInt32的声明正确,保持不变。
完成以上修改后,重新调用DLL并使用Marshal.PtrToStructure转换,nPolygonNum之后的数据即可正常解析。
内容的提问来源于stack exchange,提问作者Hussain Akbar
相关产品推荐
相关产品推荐

