未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配
出错场景
在调试海康SDK时,将struct类型的实例压入内存时,提示了改错误信息,具体代码如下:
CHCNetSDK.NET_DVR_ALARM_DEVICE_USER alarmDeviceUser = new CHCNetSDK.NET_DVR_ALARM_DEVICE_USER();
alarmDeviceUser.sPassword = Encoding.UTF8.GetBytes("a77777777");
//输入指针
IntPtr ptrInput = Marshal.AllocHGlobal(Marshal.SizeOf(alarmDeviceUser));
// 这一句话报错
Marshal.StructureToPtr(alarmDeviceUser, ptrInput, false);
错误截图如下:
错误说明
单从字面上去理解,就是长度不一样,说白了就是alarmDeviceUser和ptrInput在内存的长度不一致,导致放入内存的时候放不进去。
排除原因
一开始怎么都不知道啥原因,因为Marshal.SizeOf(alarmDeviceUser)拿到的肯定是alarmDeviceUser的长度,其他代码在海康威视中都有例子,这里面只有一句话是自己的,就是alarmDeviceUser.sPassword = Encoding.UTF8.GetBytes("a77777777")
。那这句有什么问题吗。
错误说明
通过排查可以得出来alarmDeviceUser.sPassword
默认的值是16,而如果使用这个赋值以后,他的长度变为了9。什么意思呢,就是单论alarmDeviceUser
实例的时候,sPassword长度是9;Marshal.SizeOf(alarmDeviceUser)计算长度时,sPassword默认是16。这样子就导致了长度不同。
为了便于定位问题,我们将NET_DVR_ALARM_DEVICE_USER
修改为只有sPassword,运行后可以看到nSize和sPassword大小的不同
修复问题
如何修改呢,只需要将 alarmDeviceUser.sPassword = Encoding.UTF8.GetBytes("a77777777");
修改为Encoding.UTF8.GetBytes("a77777777").CopyTo(alarmDeviceUser.sPassword, 0)
;即可。
不过如果该byte数组为null,则不会出现这个问题,应该是在StructureToPtr时,针对null的有判断。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」