VB.NET调用C DLL时如何将指针数据拷贝到自定义结构体中
错误原因
你调用的Marshal.PtrToStructure(Of T)(IntPtr, T)重载仅支持引用类型(类)参数,而你定义的DEV_EVENT_FACERECOGNITION_INFO是值类型(Structure),因此触发类型不匹配报错。
正确实现方法
使用支持值类型的重载即可完成指针到结构体的拷贝,有两种常用写法:
- 写法1:泛型返回值重载(推荐)
' 直接返回新的结构体实例,无需提前声明初始化 Dim structFaceRecognitionInfo As DEV_EVENT_FACERECOGNITION_INFO = Marshal.PtrToStructure(Of DEV_EVENT_FACERECOGNITION_INFO)(AlarmInfo)
- 写法2:非泛型重载强制转换
Dim structFaceRecognitionInfo As DEV_EVENT_FACERECOGNITION_INFO = CType(Marshal.PtrToStructure(AlarmInfo, GetType(DEV_EVENT_FACERECOGNITION_INFO)), DEV_EVENT_FACERECOGNITION_INFO)
后续兼容注意事项
如果执行后出现字段值异常、内存访问报错等问题,需要检查以下配置:
- 回调委托的
pAlarmInfo参数在VB.NET中必须声明为IntPtr类型,不能声明为其他类型 - 所有嵌套的子结构体(
NET_TIME、DH_MSG_OBJECT、CANDIDATE_INFO、NET_CUSTOM_PROJECTS_INFO)都必须添加<StructLayout(LayoutKind.Sequential)>特性,内存对齐规则和C端定义完全一致 - 结构体中的布尔字段
bIsDuplicateRemove建议补充封送特性,匹配C端4字节BOOL类型:<MarshalAs(UnmanagedType.Bool)> Public bIsDuplicateRemove As Boolean - 如果C端结构体有自定义对齐字节(比如
#pragma pack(1)),需要在结构体的StructLayout特性中指定Pack参数,例如1字节对齐的写法:<StructLayout(LayoutKind.Sequential, Pack:=1)> Public Structure DEV_EVENT_FACERECOGNITION_INFO ' 字段定义 End Structure
内容的提问来源于stack exchange,提问作者Hussain Akbar
相关产品推荐
相关产品推荐

