Anyty C++DLL封装成NetDLL进行调用
由于项目中要用到摄像头进行画面的抓拍,提供的C++动态链接库dll.但项目使用C#进行开发的,需要进行二次封装。
主要涉及到两点:
1.C++中常用的变量在C#中的映射
2.C++方法在C#中的调用
3.C++回调函数在C#中的调用
1.C++中常用的变量在C#中的映射
我主要整理了自己用到的一些变量之间的映射关系。
C++ | C# |
---|---|
int | int |
long | int |
long long | long |
2.C++方法在C#中的调用
antydll.h头文件
#pragma once
#include "ExportInterface.h"
#ifdef ANYTYDLL_EXPORTS;
#define ANYTYDLL_API __declspec(dllexport)
#else
#define ANYTYDLL_API __declspec(dllimport)
#endif
//回调函数原形
typedef void (CALLBACK *fSnapRev)(BYTE *pBuf, int width,int height, long RevLen,BOOL cap,BOOL snap);
//初始化设备
EXTERN_C ANYTYDLL_API bool InitDevice(HWND hwndFound);
//显示视频
EXTERN_C ANYTYDLL_API void DisplayVideo();
//抓拍
EXTERN_C ANYTYDLL_API void SnapPicture();
//设置回调函数
EXTERN_C ANYTYDLL_API void SetSnapRev(fSnapRev callback);
//设置图片长宽
EXTERN_C ANYTYDLL_API BOOL SetFormat(int width, int height);
//关闭设备
EXTERN_C ANYTYDLL_API void ReleaseDevice();
AnytyDLL.cpp
// AnytyDLL.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#include "ExportInterface.h"
#include "AnytyDLL.h"
#include <iostream>
using namespace std;
//HWND hwndFound;
ExportInterface inter;
BOOL isSnap = FALSE;
//设置回调函数
CALLFUNCTION CallbackFunReceiveData;
fSnapRev fSnapRevCallbackFun;
BOOL WINAPI OnReceiveData(BYTE *pBuffer, int width, int height, long datasize, BOOL cap)
{
fSnapRevCallbackFun(pBuffer, width, height, datasize,cap, isSnap);
return TRUE;
}
ANYTYDLL_API bool InitDevice(HWND hwndFound)
{
BOOL f = inter.Initialization(hwndFound);
if (f == TRUE)
{
CallbackFunReceiveData=OnReceiveData;
return true;
}
else
{
return false;
}
}
ANYTYDLL_API void DisplayVideo()
{
inter.SetCallBack(CallbackFunReceiveData);
}
ANYTYDLL_API void SnapPicture() {
isSnap = TRUE;
}
ANYTYDLL_API void SetSnapRev(fSnapRev callback)
{
fSnapRevCallbackFun = callback;
}
ANYTYDLL_API void ReleaseDevice()
{
inter.ReleaseCapture();
}
ANYTYDLL_API BOOL SetFormat(int width, int height)
{
return inter.SetFormat(width,height);
}
C#中封装成 类 AnytyClientNETl
具体对应代码如下:
public unsafe class AnytyClientNET
{
const string dllPath = @"AnytyDLL.dll";
//typedef void (CALLBACK* fSnapRev)(BYTE* pBuf, long RevLen, int width,int height);
//定义委托
public delegate void fSnapRev(IntPtr pBuf, int width, int height, int RevLen,bool cap, bool snap);
public static fSnapRev fSnapRevCallback;
//------------------------------Methods---------------------------------------------------------------------//
//bool InitDevice(HWND hwndFound)
[DllImport(dllPath, EntryPoint = "InitDevice", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static bool InitDevice(IntPtr HWND);
//void DisplayVideo()
[DllImport(dllPath, EntryPoint = "DisplayVideo", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static void DisplayVideo();
//void SnapPicture();
[DllImport(dllPath, EntryPoint = "SnapPicture", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static void SnapPicture();
//void SetSnapRev(fSnapRev callbackFun)
[DllImport(dllPath, EntryPoint = "SetSnapRev", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static void SetSnapRev(fSnapRev callback);
//void ReleaseDevice()
[DllImport(dllPath, EntryPoint = "ReleaseDevice", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static void ReleaseDevice();
//BOOL SetFormat(int width, int height)
[DllImport(dllPath, EntryPoint = "SetFormat", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
public extern static bool SetFormat(int width,int height);
}
3.C++回调函数在C#中的调用
委托的具体实现
//获取数据回调函数
private void ReceviceData(IntPtr pBuf, int width, int height, int RevLen, bool cap, bool snap)
{
byte[] buf = new byte[RevLen];
Marshal.Copy(pBuf, buf, 0, RevLen);
try
{
//Create a bitmap.
Bitmap bmp = new Bitmap(width, height);
// Retrieve the bitmap data from the the bitmap.
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//set buffer data
Marshal.Copy(buf, 0, bmpData.Scan0, buf.Length);
// unlock
bmp.UnlockBits(bmpData);
//抓拍图像
if (cap || snap)
{
var file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".jpg");
bmp.Save(file, ImageFormat.Bmp);
}
//显示画面
this.pictureBox1.Image = bmp;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
private void btnInit_Click(object sender, EventArgs e)
{
IntPtr hwnd = this.Handle;
bool res = AnytyClientNET.InitDevice(hwnd);
if (res)
{
//设置回调函数 获取数据
AnytyClientNET.fSnapRevCallback = new AnytyClientNET.fSnapRev(ReceviceData);
AnytyClientNET.SetSnapRev(AnytyClientNET.fSnapRevCallback);
//AnytyClientNET.SetFormat(1280,1024);
MessageBox.Show("初始化成功");
}
else
{
MessageBox.Show("初始化失败,请检查设备是否打开?");
}
}