最近使用C#编写一个摄像头的本地监控及录像程序,硬件开发商把全部的功能实现封装到DLL里了,本人通过C#调用之。
具体要实现的功能如下:
1、摄像头通过DAS功能,主动向监控主机的IP发送数据。
2、监控主机监听固定端口,处理接收到的数据。
本人本人的思路:
1、新建一个Dictionary存储已上线设备的信息。
2、程序初始化H264_DVR_Init(DisCallback, 0),DisCallback为断线回调函数,设备断线后将设备信息从Dictionary剔除。
3、程序通过调用DLL中的H264_DVR_StartActiveRigister(port, ActiveRegCallBack, 0))方法开始监听端口,ActiveRegCallBack为设备上线后的回调函数,能够得到上线设备的信息。
遇到的问题:
现在程序能够正常的运行,设备发送数据也能接受并显示,但是假如有一个已连接的设备断线后,当这个设备再次连接时或新设备上线时程序就崩溃,显示VSHOST32.EXE已停止工作,即使关闭项目属性中“启用visual studio承载进程”后也会崩溃。
现将部分代码贴上,感谢高手!跪谢!
具体要实现的功能如下:
1、摄像头通过DAS功能,主动向监控主机的IP发送数据。
2、监控主机监听固定端口,处理接收到的数据。
本人本人的思路:
1、新建一个Dictionary存储已上线设备的信息。
2、程序初始化H264_DVR_Init(DisCallback, 0),DisCallback为断线回调函数,设备断线后将设备信息从Dictionary剔除。
3、程序通过调用DLL中的H264_DVR_StartActiveRigister(port, ActiveRegCallBack, 0))方法开始监听端口,ActiveRegCallBack为设备上线后的回调函数,能够得到上线设备的信息。
遇到的问题:
现在程序能够正常的运行,设备发送数据也能接受并显示,但是假如有一个已连接的设备断线后,当这个设备再次连接时或新设备上线时程序就崩溃,显示VSHOST32.EXE已停止工作,即使关闭项目属性中“启用visual studio承载进程”后也会崩溃。
现将部分代码贴上,感谢高手!跪谢!
//-- //初始化SDK public void InitSDK() { DisCallback = new XMSDK.DisConnectCallBackDelegate(DisConnectBackCall); GC.KeepAlive(DisCallback); if (XMSDK.H264_DVR_Init(DisCallback, 0)) { Console.Write(NowTime() + "系统初始化,成功!"); 系统实时信息.AppendText(DateTime.Now.ToLongDateString().ToString() + DateTime.Now.ToLongTimeString().ToString() + " : " + "系统初始化,成功!"); File.AppendAllText(LogSavePath, NowTime() + "系统初始化,成功!", Encoding.UTF8); } else { Console.Write(NowTime() + "系统初始化,失败!"); 系统实时信息.AppendText(NowTime() + "系统初始化,失败!"); File.AppendAllText(LogSavePath, NowTime() + "系统初始化,失败!", Encoding.UTF8); } } //-- //断线回掉函数,输出断线信息,停止RealPlay、PC端录像 void DisConnectBackCall(int lLoginID, string pchDVRIP, int nDVRPort, IntPtr dwUser) { ActiveRegListStruct ActiveRegListOne; ActiveRegList.TryGetValue(lLoginID, out ActiveRegListOne); Message = new MessageStruct(); Message.msg = "设备:" + ActiveRegListOne.RasID + "(" + ActiveRegListOne.SerialNumber + ")" + ",断线!"; ShowMessage(); if (XMSDK.H264_DVR_StopLocalRecord(ActiveRegListOne.RealPlayID)) { ActiveRegListOne.RecordingTime = -1; Message = new MessageStruct(); Message.msg = "设备:" + ActiveRegListOne.RasID + "(" + ActiveRegListOne.SerialNumber + ")" + ",停止PC端录像!"; ShowMessage(); } if (XMSDK.H264_DVR_StopRealPlay(ActiveRegListOne.RealPlayID, (uint)ActiveRegListOne.Handle)) { ActiveRegListOne.RealPlayID = -1; Message = new MessageStruct(); Message.msg = "设备:" + ActiveRegListOne.RasID + "(" + ActiveRegListOne.SerialNumber + ")" + ",停止实时监视!"; ShowMessage(); } if (ActiveRegList.ContainsKey(lLoginID)) { ActiveRegList.Remove(lLoginID); } AddToTreeView(); } //-- //设备主动注册 public void StartActiveRigister() { int port = 9300; ActiveRegCallBack = new XMSDK.ActiveRigisterCallBackDelegate(ActiveRigisterCallBack); if (XMSDK.H264_DVR_StartActiveRigister(port, ActiveRegCallBack, 0)) { PrintMessage("远程设备主动注册监听,成功!"); PrintMessage("开始监听:" + port.ToString() + "端口,等待设备连接。"); } else { PrintMessage("远程设备主动注册监听开始,失败!"); } } //-- //主动监听回调函数 public void ActiveRigisterCallBack(int lLoginID, IntPtr pBuf, uint dwBufLen, uint dwUser) { H264_DVR_ACTIVEREG_INFO ActiveClientInfo; ActiveClientInfo = (H264_DVR_ACTIVEREG_INFO)Marshal.PtrToStructure(pBuf, typeof(H264_DVR_ACTIVEREG_INFO)); if (ActiveRegList.Count < 6) { ActiveRegListStruct ActiveRegListOne; ActiveRegListOne.LoginID = lLoginID; ActiveRegListOne.RasID = ActiveClientInfo.deviceSarialID; ActiveRegListOne.SerialNumber = ActiveClientInfo.deviceInfo.sSerialNumber; ActiveRegListOne.VideoOutChannel = ActiveClientInfo.deviceInfo.iVideoOutChannel; ActiveRegListOne.deviceInfo = ActiveClientInfo.deviceInfo; ActiveRegListOne.RealPlayID = -1; ActiveRegListOne.RecordingTime = -1; ActiveRegListOne.isSetKeepLifeTime = XMSDK.H264_DVR_SetKeepLifeTime(lLoginID, 1, 1 * 2); ActiveRegListOne.Handle = HandleArray[ActiveRegList.Count]; ActiveRegList.Add(lLoginID, ActiveRegListOne); NowActiveReg = ActiveRegListOne; //-- //更新设备列表TreeView AddToTreeView(); //-- //开始RealPlay和PC端录像 StartRealPlayLocalRecord(); } else { MessageBox.Show("当前连接数过多,本系统最多支持6个通道连接!"); } }
解决方案
1
这个要找厂家解决吧。
39
只看这些不好分析,
建议lz在重新连接\注册的地方加上try…catch
先判定崩溃是发生在
c native code还是 c# code
假如发生在c dll ,那就得关注资源释放能否完成。
建议lz在重新连接\注册的地方加上try…catch
先判定崩溃是发生在
c native code还是 c# code
假如发生在c dll ,那就得关注资源释放能否完成。