您的位置:首页 > 编程语言 > C语言/C++

C# 调用C/C++回调函数

2015-11-16 17:10 691 查看
C/C++内回调函数一般通过传递函数指针来实现,函数指针在C#中对应的就是委托. // PerformClick 调用按钮事件Cpp代码


// 传入函数指针

typedef int (CALLBACK* DS_SNAP_PROC)(INT iCamID, BYTE *pImageBuffer, tDSFrameInfo *psFrInfo);

Cpp代码


public delegate int DelegateProc(int m_iCam, ref Byte pbyBuffer, ref tDSFrameInfo sFrInfo); //声明委托

// 接口定义

[DllImport("DVP_CAMSDK.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern emDSCameraStatus CameraInit(DelegateProc pCallbackFunction, String lpszFriendlyName, IntPtr hWndDisplay, ref int piCameraID);

//调用示例

Camera.DelegateProc psub=psub = new Camera.DelegateProc(SnapThreadCallback);

Camera.CameraInit(psub, m_sCameraName, PictureBox.Handle, ref m_iCameraID); //最好声明委托实例为static,防止垃圾回收器的回收

然后我们就可以在CallbackFunc里面编写回调逻辑了,而JNA回调以interface作为参数,两者相差不大. C#代码


// 回调函数

public static int SnapThreadCallback(int m_iCam, ref Byte pbyBuffer, ref tDSFrameInfo sFrInfo)

{

int pBmp24 = Camera.CameraISP(m_iCam, ref pbyBuffer,ref sFrInfo);

Camera.CameraDisplayRGB24(m_iCam, pBmp24, ref sFrInfo);

if (m_bVideo)

{

Camera.CameraRecordFrame(m_iCam, pBmp24, ref sFrInfo);

}

return 0;

}

示例:

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());
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: