c#调用DLL回调函数问题,硬盘录像机,NetSdk.dll,H264_DVR

问题描述

c#调用DLL回调函数问题,硬盘录像机,NetSdk.dll,H264_DVR

最近使用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承载进程”后也会崩溃。

现将部分代码贴上,感谢大神!跪谢!

//----------------------------------------------------------------------------------------------------
//初始化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个通道连接!");
        }
    }

class XMSDK
{
public delegate void DisConnectCallBackDelegate(int lLoginID, string pchDVRIP, int nDVRPort, IntPtr dwUser); //断线回调函数,回调出当前已经断开的设备
public delegate void ActiveRigisterCallBackDelegate(int lLoginID, IntPtr pBuf, uint dwBufLen, uint dwUser);
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_Init(DisConnectCallBackDelegate cbDisConnect,uint dwUser); //SDK初始化
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_StartActiveRigister(int nPort, ActiveRigisterCallBackDelegate cbFunc, uint dwDataUser); //远程设备主动注册监听
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_StopActiveRigister(); //远程设备主动注册监听
[DllImport("NetSdk.dll")]
public static extern int H264_DVR_RealPlay(int lLoginID, ref H264_DVR_CLIENTINFO lpClientInfo);
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_StopRealPlay(int lLoginID, uint dwUser);
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_StartLocalRecord(int lRealHandle, string szSaveFileName, int type);
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_StopLocalRecord(int lRealHandle);
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_SetKeepLifeTime(int lLoginID, int perKeeplifeTime, int detectDisconTime);
[DllImport("NetSdk.dll")]
public static extern int H264_DVR_GetLastError();
[DllImport("NetSdk.dll")]
public static extern bool H264_DVR_Cleanup();
}

public struct ActiveRegListStruct
{
    public int LoginID;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public String RasID; //RAS-ID 类似于laizhou
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
    public String SerialNumber;//设备序列号 MAC地址 唯一标识符
    public int VideoOutChannel; //单个设备输出通道数
    public bool isSetKeepLifeTime; //设置心跳时间是否成功的返回值,1 成功,0 失败
    public int RealPlayID;  //执行RealPlay方法的返回值,用于LoaclRecord
    public int RecordingTime;//显示已录像多长时间,-1为没有开始录像
    public IntPtr Handle; //Handle
    public H264_DVR_DEVICEINFO deviceInfo;

}

//----------------------------------------------------------------------------------------------------
//已连接的设备列表
public static Dictionary ActiveRegList = new Dictionary();

解决方案

既然dll 里有所有内容,那你就看api, 查查断线重连用哪个方法

时间: 2025-01-30 03:44:47

c#调用DLL回调函数问题,硬盘录像机,NetSdk.dll,H264_DVR的相关文章

delphi-Delphi 调用C++ dll 回调函数

问题描述 Delphi 调用C++ dll 回调函数 用Delphi 调用容联云通信的动态库CCPAppClient.DLL,其中有一个函数 Function CCPinit( CallbackInterface: CCPCALLBACKINTERFACE ):Integer;stdcall; 参数CCPCALLBACKINTERFACE 是一个结构体指针,包含 onConnected , onConnectError 等回调函数. 在调用函数CCPinit调用成功后(返回值0),会触发CCPC

Windows Service中调用dll 回调函数不执行(在线等)

问题描述 WindowsService中调用dll回调函数不执行,非回调函数正常:部分代码publicdelegatevoidGESCALLBACK(stringExtNum,intstatus);[DllImport("ExtStatusShow.dll")]publicstaticexternintRegGetExtStatusCBEvent(GESCALLBACKFunc);...publicvoid_UpdateExtStatus(stringExtNum,intstatus)

海康硬盘录像机dll-c#开发用户控件引用海康硬盘录像机的dll时报800700B错误

问题描述 c#开发用户控件引用海康硬盘录像机的dll时报800700B错误 项目目标平台设置为anycpu的情况下开的应用程序调用海康硬盘录像机dll时程序正常运行,可是winform开发用户控件时调用海康硬盘录像机的dll时报8007000b错误:大神们怎么解决这个问题. 解决方案 应该是接口使用错误,包括封送的数据类型,最好看看他们提供的demo

com组件-Com组件调用C++回调函数,如何传参

问题描述 Com组件调用C++回调函数,如何传参 一.com组件接口函数的实现: 1.成员 private: //回调函数指针 CComPtr m_pChangeTempCallbackFun;//更换模板回调函数 2.函数 bool CDllHelper::SetCallBackFun(VARIANT vaJsFun) { if(vaJsFun.vt != VT_DISPATCH) { return false; } m_pChangeTempCallbackFun = vaJsFun.pdi

在C#里面调用带有回调函数和自定义结构体的DLL的例程

函数 开发环境: WinXP Pro(SP2英文版) + VS.NET 2003中文版接口库版本: CMPP2.0 API第二版(V2.6) 该例程演示了如何在C#里面调用VC6.0开发的带回调函数的API,而且回调函数的参数包含结构体,使用C#的委托和IntPtr方法实现. 由于我使用C#刚两天,这是我写的第一个C#程序,因此例程写的可能有点粗糙,但是编译和运行完全没有问题. CMPP2.0的API封装成了标准C调用的方法,提供以下三个接口,使用的时候只要有CMPPAPI.dll就可以了. #

C#调用带有回调函数的DLL的问题 !!!!急!!!!!!

问题描述 //------------dll中的回调函数---------------voidkinescope(void(*kines)(floatx,floaty)){D3DXVECTOR3vec=d3d->GetCamera()->GetPos();kines(vec.x,vec.y); //----------------C#中调用代码---------------//------------委托声明-------------publicdelegatevoidkinds(floatx

C++调用C++写的DLL回调函数,只能传递第一个参数

问题描述 好不容易能够实现回调了,结果验证数据的时候发现,最后执行到DoWhile_Get_StatusChange的时候,本来是两个int参数的,只有第一个的值传递了过来,第二个参数的值一直是0.不知道是啥原因了C++的DLL里面是这样的代码aaaa_Lib.cpp//-------------------------------------------------------------------------------//声明typedefbool(CALLBACK*Connection

C#调用C++回调函数的问题

C++的回调函数中有一个参数是,是返回一个字符串,原则如下: typedef void (*TDataEvent)(char *AData ,int ALen); 其中char *AData是从DLL中返回一个字符串,串的内存已经在DLL中分配了 下面中我在C#中定义的委托 public delegate void TDataEvent(Byte[] AData, int ALen); 下面是回调函数的设置代码: Event=new clReceivelDllPoxy.TDataEvent(ge

c++调用c#的dll时回调函数该如何处理

问题描述 c++调用c#的dll时回调函数该如何处理 比如该c#的dll中,服务器连接的函数会回调一个A方法.那么我在c++中只需要实现这个A方法,还是需要把整个回调逻辑再实现一遍.... 解决方案 回调函数在C#中用委托封装.具体的做法,你可以参考windows api中有回调的函数,以及对应的C#的调用.比如enumwindowshttp://blog.csdn.net/dengta_snowwhite/article/details/6067928 解决方案二: C#调用c++dll时,关