当前位置:编程学习 > VB >>

将vc实现的回调函数改为vb语言(海康dvr)

最近在用vb结合海康的dvr做视频监控的项目,预览、控制球机都可以了,但是想捕获摄像头的报警信息时用到回调函数,在vb中不知如何转换了。
vc的实现方法是:
typedef void (CALLBACK *MSGCallBack)(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);
NET_DVR_API BOOL __stdcall NET_DVR_SetDVRMessageCallBack_V30(MSGCallBack fMessageCallBack, void* pUser);
我在vb中这样写了:Public Declare Function NET_DVR_SetDVRMessageCallBack_V30 Lib "HCNETSDK.dll" ( _
               ByVal fMessageCallBack As MSGCallBack, _
               ByVal pUser As Long _
) As Boolean
Public Sub MSGCallBack( _
       ByVal lCommand As Long, _
       ByVal dwDataType As Long, _
       ByVal dwBufSize As Long, _
       ByVal pUser As Long)
End Sub
但是, ByVal fMessageCallBack As MSGCallBack, _报错,请问哪位能指教一下,谢谢。 楼主,你试下这样行不:
' 标准模块中的代码:
Public Declare Function NET_DVR_SetDVRMessageCallBack_V30 Lib "HCNETSDK.dll" ( _
                              ByVal fMessageCallBack As Long, ByVal pUser As Long) As Boolean


Public Sub MSGCallBack( _
       ByVal lCommand As Long, _
       ByVal dwDataType As Long, _
       ByVal dwBufSize As Long, _
       ByVal pUser As Long)
' 这个函数的具体实现…………
   ' .......
   ' .......
   ' .......
   ' .......
End Sub

' 示例:
Private Sub Command1_Click()
   Dim retVal As Boolean
   ' NET_DVR_SetDVRMessageCallBack_V30( ) 调用示例, xxxxx按你的实际情况写
   retVal = NET_DVR_SetDVRMessageCallBack_V30(AddressOf MSGCallBack, xxxxx)
   
End Sub
谢谢,我也像这样改了试过,但还是有错误,NET_DVR_SetDVRMessageCallBack_V30(AddressOf MSGCallBack, xxxxx)到这一步就会非法跳出子函数了。我是这样写的   If NET_DVR_SetDVRMessageCallBack_V30(AddressOf MSGCallBack, IntPtr.Zero) Then
'                {
                    Debug.Print "NET_DVR_SetDVRMessageCallBack_V30 Succ"
'                }

c#有个例子是这样实现的:
  m_falarmData = new CHCNetSDK.MSGCallBack(MsgCallback);
                if (CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V30(m_falarmData, IntPtr.Zero))
                {
                    DebugInfo("NET_DVR_SetDVRMessageCallBack_V30 Succ");
                }
                else
                {
                    uint i = CHCNetSDK.NET_DVR_GetLastError();
                    DebugInfo("NET_DVR_SetDVRMessageCallBack_V30 Fail");
                }

  /*********************************************************
        Function: MSGCallBack
        Desc: (回调函数)
        Input:
        Output:
        Return:
        **********************************************************/
        public delegate void MSGCallBack(int lCommand, ref NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser);

        [DllImport("HCNetSDK.dll")]
        public static extern bool NET_DVR_SetDVRMessageCallBack_V30(MSGCallBack fMessageCallBack, IntPtr pUser);


        public void MsgCallback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            MyDebugInfo AlarmInfo = new MyDebugInfo(DebugInfo);
            switch (lCommand)
            {
                case CHCNetSDK.COMM_ALARM:
                    ProcessCommAlarm(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CHCNetSDK.COMM_ALARM_V30:
                    ProcessCommAlarm_V30(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CHCNetSDK.COMM_ALARM_RULE:
                    this.BeginInvoke(AlarmInfo, "COMM_ALARM_RULE");
                    break;
                case CHCNetSDK.COMM_TRADEINFO:
                    this.BeginInvoke(AlarmInfo, "COMM_TRADEINFO");
                    break;
                case CHCNetSDK.COMM_IPCCFG:
                    this.BeginInvoke(AlarmInfo, "COMM_IPCCFG");
                    break;
                case CHCNetSDK.COMM_IPCCFG_V31:
                    this.BeginInvoke(AlarmInfo, "COMM_IPCCFG_V31");
                    break;
                default:
                    break;
            }
        }
引用 2 楼 ysfxincsdn 的回复:
谢谢,我也像这样改了试过,但还是有错误,NET_DVR_SetDVRMessageCallBack_V30(AddressOf MSGCallBack, xxxxx)到这一步就会非法跳出子函数了。我是这样写的   If NET_DVR_SetDVRMessageCallBack_V30(AddressOf MSGCallBack, IntPtr.Zero) Then
'                {
                    Debug.Print "NET_DVR_SetDVRMessageCallBack_V30 Succ"
'                }
.........
        }


你那个 IntPtr.Zero 是什么东东???
按函数原型的“参数”来看,应该是一个“用户名字符串”的指针啊……
我跟踪了c#的例子,IntPtr.Zero就是0 你也做过海康dvr的二次开发?能参考一下你的代码吗?(主要就是获取报警通道号这块)我是初次接触,对vb还不太熟悉,但是已有项目是vb开发的,所以有点难度。475076893@qq.com 我没搞过这些,写代码是业余爱好罢了。
引用 4 楼 ysfxincsdn 的回复:
我跟踪了c#的例子,IntPtr.Zero就是0

那你也可以传个 0 给它,试试啊。

还有,我很怀疑是你的 MSGCallBack( )中处理不正确造成的错误。
你可以先试下,把它内部的代码全部注释掉。
然后,写一、两句普通代码,比如 定义一个局部Long变量,然后就写一句随便赋个值的。
如果可以在IDE下运行,可以写一句: debug.print lCommand, dwDataType ,dwBufSize ,pUser
或者写句 msgbox 语句,看能不能被执行到、会不会再造成错误。

从你提供的信息来看,NET_DVR_SetDVRMessageCallBack_V30( )就是应该象我在 1F 说的那样声明和使用。
不要做A语言代码修改为B语言代码的无用功。
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。
引用 8 楼 zhao4zhong1 的回复:
不要做A语言代码修改为B语言代码的无用功。
也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。
只需让A、B语言代码的输入输出重定向到文本文件,或修改A、B语言代码让其通过文本文件输入输出。
即可很方便地让A、B两种语言之间协调工作。

又见 XXX点读机…………
补充:VB ,  API
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,