📢本文作者:由webmote 原创
📢作者格言:新的征程,我们面对的不仅仅是技能还有民气,民气不可测,海水不可量,唯有技能,才是深奥深厚黑夜中的一座闪烁的灯塔 !
在工控领域,很多时候须要访问和掌握海康相机,通过程序掌握海康相机可以实现变倍变焦,拍照,抓取视频平分歧的操作。海康的SDK是C++编写的Dll,由于没有很好的进行包装,利用起来还是比较麻烦的,并且随着海康SDK的版天职歧,各种版本有许多差异性,不好的封装会导致有很多的问题,这里把踩过的坑列举下,以便后来者少踩坑。

1. 一个进程只能加在一个海康DLL
在许多的运用中,有时候会欠妥心有多个类库,如果重复引用了海康DLL,会导致C#在调用海康威视CHCNetSDK涌现未能从程序集中加载类型“WIFI_AUTH_PARAM”,由于它在 0 偏移位置处包含一个工具字段,该字段已由一个非工具字段禁绝确地对齐或重叠。
很多的处理方案是把全体文件接口体头部的LayoutKind.Explicit改为LayoutKind.Auto,删除所有[FieldOffset(0)]
,这个从措辞体系上来说是缺点的,但方法又是可行的,为啥?
根本缘故原由是你没有用到此构造体而已,一旦有引用,那么很可能带来不必要的麻烦。
因此,涌现问题不要慌,仔细查找干系库,是不是有多次引用海康库的问题,就可以从根本上办理该问题。
2.监测海康相机是否还在线,或登录过期很多同学采取ping
办法进行监测,不得不说,这是最低级的方案,它根本无法检测登录过期问题,精确的做法是利用SDK中的利用userid的函数,我这里挑了个大略的方法进行检测,非常好用,大家不妨拿来用:
public bool CheckDevice(int userId){IntPtr addr = IntPtr.Zero;uint nOutSize = 0;try{int nInSize = Marshal.SizeOf<CHCNetSDK.NET_DVR_TIME>(); addr = Marshal.AllocHGlobal(nInSize);var rtn = CHCNetSDK.NET_DVR_GetDVRConfig(userId, CHCNetSDK.NET_DVR_GET_TIMECFG, 0, addr, (uint)nInSize, ref nOutSize);var dvrTime = Marshal.PtrToStructure<CHCNetSDK.NET_DVR_TIME>(addr);return rtn;}catch{return false;}finally{if (addr != IntPtr.Zero){try{ Marshal.FreeHGlobal(addr);}catch { }}}}
利用CheckDevice
函数,就可以对海康设备的通断情形进行直接检测,不但效率比ping
高,而且可靠易用。
引用有几种办法,最大略的办法是直策应用 DllImportAttribute
属性进行,大略方便,只须要记得把海康的dll文件放在实行根目录的相对路径下即可。
[DllImport(@\公众\HkSdk\HCNetSDK.dll\"大众)]public static extern bool NET_DVR_STDXMLConfig(int iUserID, ref NET_DVR_XML_CONFIG_INPUT lpInputParam, ref NET_DVR_XML_CONFIG_OUTPUT lpOutputParam);...//这个文件该当都有吧...public class CHCNetSDK{public CHCNetSDK(){//// TODO: 在此处添加布局函数逻辑//}//2019 3.1添加[StructLayoutAttribute(LayoutKind.Sequential)]public struct NET_DVR_XML_CONFIG_INPUT{public uint dwSize;//构造体大小 public IntPtr lpRequestUrl;//要求信令,字符串格式 public uint dwRequestUrlLen;public IntPtr lpInBuffer;//输入参数缓冲区,XML格式 public uint dwInBufferSize;public uint dwRecvTimeOut;//吸收超时时间,单位:ms,填0则利用默认超时5s [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]public byte[] byRes;}[StructLayoutAttribute(LayoutKind.Sequential)]public struct NET_DVR_XML_CONFIG_OUTPUT{public uint dwSize;//构造体大小 public IntPtr lpOutBuffer;//输出参数缓冲区,XML格式 public uint dwOutBufferSize;public uint dwReturnedXMLSize;//实际输出的XML内容大小 public IntPtr lpStatusBuffer;//返回的状态参数(XML格式:ResponseStatus),获取命令成功时不会赋值,如果不须要,可以置 public uint dwStatusSize;//状态缓冲区大小(内存大小) [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 32, ArraySubType = UnmanagedType.I1)]public byte[] byRes;}}
还有如果须要支持linux平台,以及windows的x86和x64,那么须要更多的封装,如果有须要可以留言。
4. SDK的初始化海康SDK在利用的时候,须要进行SDK的初始化,在退出时,须要销毁资源,这里的资源属于非托管资源,因此请谨慎反复调用。
CHCNetSDK.NET_DVR_Cleanup();if (!CHCNetSDK.NET_DVR_Init()){throw new Exception(\"大众海康相机初始化失落败:调用NET_DVR_Init()方法返回false\公众);}
5. 登录登出
海康SDK支持限定并发连接到海康设备,因此频繁登入可能导致46缺点,我们利用的时候,记得配对利用,避免引入bug。
var userID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref deviceInfo);HCNetSDK.NET_DVR_Logout_V30(userID);
6.缺点解析和输出
像大多数c++类库一样,它们都是采取一个特定函数获取缺点码的。
public string GetErrorDetail(){var errorCode = CHCNetSDK.NET_DVR_GetLastError(); LastErrorCode = errorCode;return string.Format(\"大众缺点码:{0}\"大众, errorCode);}
7.结论
我这里没有供应封装好的类库,这该当是有大量需求的,海康自己也没有很好的进行封装,我操持后面会供应一个,先发文章看看是否有需求了,大家可以评论给我。
你学废了吗?
👓都收藏了,还在乎一个评论吗?