可能 fMessCallBack k 的参数有返回类型把.

解决方案 »

  1.   


    这个C++dll不是只调用一次回调函数。而我换成C#之后却只调用一次,是代码问题应该。不知哪里有错,能给点指点吗!
      

  2.   

    你首先得知道
    [DllImport(strDll)]
          public static extern bool NET_DVR_SetDVRMessCallBack(fMessCallBack k);
    这个函数到底是干什么用的.还有回调的这三个参数int lCommand, string sDVRIP, IntPtr pBuf,ulong dwBufLen到底是干什么用的.
    我猜测楼主的意思是NET_DVR_SetDVRMessCallBack里执行了一个递归,为什么只递归了一次.
    所以就要看看回调的那三个三数到底有什么用了
    循环几起基本上是取决于NET_DVR_SetDVRMessCallBack里到底怎么执行的,而不是你单纯的pcount = pcount + 1;我看你代码完全看不出有循环的意思,好歹你也写成:
    while(pcount<10)
    {
    aaa.NET_DVR_SetDVRMessCallBack(fcb);
    pcount++;
    }
      

  3.   


    首先谢谢你这么有耐心,我解释一下这个回调函数的作用,这是个视频行为分析报警的回调函数,当视频里有触犯规则的图象发生就跳到这个回调函数里。pcount不做循环,我就想知道一下运行回调函数的次数,做个记数。
      

  4.   

    C++的原型
    NET_DVR_API BOOL __stdcall NET_DVR_SetDVRMessCallBack(BOOL (CALLBACK *fMessCallBack)(LONG lCommand,char *sDVRIP,char *pBuf,DWORD dwBufLen));谢了~~
      

  5.   

    你能看到C++的代码吗?你最好去看看C++里NET_DVR_SetDVRMessCallBack这个函数到底调用了多少次,若是只调用了一次而会执行多次回调函数的话,那你在找找为什么会执行多次回调函数.
    这是个视频行为分析报警的回调函数,当视频里有触犯规则的图象发生就跳到这个回调函数里.
    那意思就是一直在侦听,可能是每侦听到非法的图象就会执行一次NET_DVR_SetDVRMessCallBack,从而执行了多次回调.而你在C#里调用时确定在不停的捕获非法图象吗?你现在C#代码里只执行了一次aaa.NET_DVR_SetDVRMessCallBack(fcb);我觉得突破口还是你好好看看C++里的NET_DVR_SetDVRMessCallBack到底是怎么执行的,我觉得有两总可能,一种就是前面我说的调用了多次NET_DVR_SetDVRMessCallBack,还一种就是调用了一次NET_DVR_SetDVRMessCallBack,却递归调用了多次回调函数.如果是递归调用了多次函数,那么你C#只执行一次aaa.NET_DVR_SetDVRMessCallBack(fcb);是没有问题的,那就要看递归结束的条件在你C#代码里有没有处理了
      

  6.   

    这是C++的代码 int CALLBACK MessageCallback(LONG lCommand,char *sDVRIP,char *pBuf,DWORD dwBufLen,WORD dwLinkDVRPort)
    {
    DWORD   dwCounter = 0;           // 计数器值
    NET_VCA_BEHAVIOR_ANALYSE_RESULT struBehaviorResult;
    memcpy(&struBehaviorResult, pBuf, sizeof(NET_VCA_BEHAVIOR_ANALYSE_RESULT));
    dwCounter = struBehaviorResult.struCounter.dwCounterFirst + struBehaviorResult.struCounter.dwCounterSecond;
    return 0;
    }
    void CDemoDlg::OnButton1() 
    {
    // TODO: Add your control notification handler code here CString sTemp;
    CString m_ServerName      = _T("Test");       // 服务器名
    char    m_chDeviceIp[16]  = "192.0.0.64";   // 设备IP地址
    short m_ServerPort      = 8000;             // 服务器端口
        char    m_chUserName[100] = "kk";          // 用户名
    char    m_chPassword[100] = "12345";       // 用户名密码
    NET_DVR_NETCFG netcfg;                        // 用于保存其多播参数
    DWORD dwReturned = 0;
    NET_DVR_DEVICEINFO DeviceInfo;
    int m_lUserID = NET_DVR_Login(m_chDeviceIp, m_ServerPort, m_chUserName, m_chPassword, &DeviceInfo);
    if(m_lUserID < 0)
    {
    CString sTemp;
    int nErr = NET_DVR_GetLastError();  
    sTemp.Format("ERROR: NET_DVR_Login = %d", nErr);
    TRACE(sTemp);
    if(nErr == NET_DVR_PASSWORD_ERROR)
    {
    AfxMessageBox("用户名密码错误!");
    }
    else
    {
    AfxMessageBox("由于网络原因或DVR忙, 注册失败!");
    }
    }
    if(!NET_DVR_GetDVRConfig(m_lUserID, NET_DVR_GET_NETCFG, 0,&netcfg, sizeof(NET_DVR_NETCFG), &dwReturned))
    {
    CString sTemp;
    sTemp.Format("获取服务器配置信息失败: NET_DVR_GET_NETCFG = %d \n", NET_DVR_GetLastError());
    TRACE(sTemp);
    }
        
    NET_VCA_BEHAVIOR_ABILITY struAbility;
    LPNET_DVR_CLIENTINFO lpClientInfo;
    memset(&struAbility, 0, sizeof(NET_VCA_BEHAVIOR_ABILITY));
    if(!NET_DVR_GetBehaviorAbility(m_lUserID, 1, &struAbility))
    {
    sTemp.Format("%d : ERROR: NET_DVR_GetBehaviorAbility = %d \n", 1, NET_DVR_GetLastError());
    TRACE(sTemp);
    AfxMessageBox(sTemp);
    } // 默认客户端启动时 对设备自动布防
    NET_DVR_SetupAlarmChan(m_lUserID); NET_DVR_SetDVRMessCallBack_NEW(MessageCallback);//回调

    }
      

  7.   

    DWORD   dwCounter = 0;           // 计数器值
            NET_VCA_BEHAVIOR_ANALYSE_RESULT struBehaviorResult;
            memcpy(&struBehaviorResult, pBuf, sizeof(NET_VCA_BEHAVIOR_ANALYSE_RESULT));
            dwCounter = struBehaviorResult.struCounter.dwCounterFirst + struBehaviorResult.struCounter.dwCounterSecond;
    把C++这段注释掉看是不是也只执行一次,如果是的话,那就和pbuf参数返回值有关。
      

  8.   

    就象:        public int add(int n)
            {
                int sum = 0;
                if (n > 0)
                {
                    sum = n + add(n - 1);
                }
                return sum;
            }就象这个递归,结束的条件是n=0,add(5)就是:5+4+3+2+1 
    到n=0的时候就结束了
      

  9.   

    把这个函数帖出来看看把NET_DVR_SetDVRMessCallBack_NEW
    根本没看见你怎么调用回调函数的,我只看见你有声明并实现了一个回调函数,然后把回调函数做为参数传到了NET_DVR_SetDVRMessCallBack_NEW里面.具体就要看NET_DVR_SetDVRMessCallBack_NEW里面给回调函数赋的参数是什么了,跟char *pBuf传进的去的值应该脱不了关系,因为看你有写:
    memcpy(&struBehaviorResult, pBuf, sizeof(NET_VCA_BEHAVIOR_ANALYSE_RESULT));
    我猜测是把PBuf拷贝到struBehaviorResult中去,不知道是不是猜对.C++里是通过dwCounter = struBehaviorResult.struCounter.dwCounterFirst + struBehaviorResult.struCounter.dwCounterSecond;
    来计数的,而struBehaviorResult又是参数char *pBuf拷贝过去的.而你看你C#的回调函数:
            public void callback(int lCommand, string sDVRIP, IntPtr pBuf, ulong dwBufLen)
            {
               pcount = pcount + 1;        }
    根本没用到回调函数的参数,因此计数器不垒加.