C# 调用C++动态库回调函数

时间:2022-11-06 19:01:06

C#调用C++库,C++库中有回调函数。

C++ 接口如下

typedef long (CALLBACK *MidwareDeviceCallBack)(void* pData, long lDataLen,long lPackType, long lSubType,int lSmartType, void* pUserData);

 long ConnectMidwareDvsDevice(long lHandle,char* chMac,MidwareDeviceCallBack deviceCallBack, void* pUserData);

回调函数中 pData 是结构体如下

  • 返回第一个参数结构
    typedef struct _MidWareHistoryPc
    {
     char   mac[20];  //MAC地址,唯一标识
     unsigned long  channel;  //属于哪个通道的智能数据
     unsigned long  alarmType;  //报警类型
     char    startTime[20]; //开始时间,返回形如"YYYY-MM-DD hh:mm:ss" ,秒数必须是10的整数倍
     char    stopTime[20]; //结束时间,返回形如"YYYY-MM-DD hh:mm:ss" ,秒数必须是10的整数倍  
     unsigned long   interval;       //时间(单位秒)间隔,为10秒的整数倍,为请求历史数据时候传入的时间间隔!
     unsigned long  persionIn;  //到目前位置检测到的进入人数
     unsigned long persionOut;  //到目前为止检测到的出去人数
     char   resver[8];
    }MIDWARE_HISTORY_PC; //数人智能历史数据上传结构体

     

     

    注意C++中的long(32位) 和C#long(64位) 是不同的

    注意结构体定义.和指针转结构体。

    c# 代码如下

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;//调用DLL需要的引用
    namespace WindowsFormsApplication1
    {

     //返回第一个参数结构
    //数人
         public struct MIDWARE_HISTORY_PC
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string mac;//MAC地址,唯一标识
            public  uint  channel;  //属于哪个通道的智能数据
            public  uint  alarmType;  //报警类型
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string startTime;//开始时间,返回形如"YYYY-MM-DD hh:mm:ss" ,秒数必须是10的整数倍
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string stopTime;//结束时间,返回形如"YYYY-MM-DD hh:mm:ss" ,秒数必须是10的整数倍 
            public  uint   interval;       //时间(单位秒)间隔,为10秒的整数倍,为请求历史数据时候传入的时间间隔!
            public  uint  persionIn;  //到目前位置检测到的进入人数
            public  uint persionOut;  //到目前为止检测到的出去人数
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
            public string resver;//结束时间,返回形如"YYYY-MM-DD hh:mm:ss" ,秒数必须是10的整数倍 
        } ;
         public delegate uint MidwareDeviceCallbackDelegate(IntPtr pData, uint lDataLen, uint lPackType, uint lSubType, int lSmartType, byte[] pUserData);


        public partial class Form1 : Form
        {
          

            public Form1()
            {
                InitializeComponent();

              
            }
            [DllImport("MidwareServer.dll")]
            public static extern uint ConnectMidwareDvsDevice(uint lHandle, byte[] chMac, MidwareDeviceCallbackDelegate deviceCallBack, byte[] pUserData);


            public static uint MidwareDeviceCallBack(IntPtr pData, uint lDataLen, uint lPackType, uint lSubType, int lSmartType, byte[] pUserData)
            {
                //Marshal.
                //IntPtr ptr;
                MIDWARE_HISTORY_PC info = new MIDWARE_HISTORY_PC();
                info = (MIDWARE_HISTORY_PC)Marshal.PtrToStructure(pData, typeof(MIDWARE_HISTORY_PC));

                MessageBox.Show("回调成功" + "alarm type = " + info.alarmType + "  alarm channe = " + info.channel);
                return 0;
            }
            private void button1_Click(object sender, EventArgs e)
            {
                MidwareDeviceCallbackDelegate funCallback = new MidwareDeviceCallbackDelegate(MidwareDeviceCallBack);
                uint nRet = ConnectMidwareDvsDevice(0, null, funCallback, null);
                MessageBox.Show("返回值 = " + nRet.ToString());

            }
        }
    }