PInvoke对接IP摄像头的笔记

最近做项目的时分,需求对接厂商供给的IP摄像头。但是他们只供给了C++的SDK,没办法,只能开始撸C#的SDKHelper类。本篇文章首要记载了对接C++DLL需求留意的几个当地,以及常见类型的转换。

要对接C++的DLL,首先得知道怎么引证DLL内的办法。在C#傍边,只需求编写契合C++的函数签名,再运用[DllImport]特性指定DLL文件途径和进口点等参数即可。
假如你需求运用Win32API供给的办法,这儿我以SetProcessDPIAware函数为例:

C#


Copy
publicstaticclassWin32Helper{
[DllImport(“user32.dll”)]publicstaticexternboolSetProcessDPIAware();
}
接下来你只需求像运用静态办法相同,调用Win32Helper.SetProcessDPIAware()办法即可。
对接DLL时的问题记载#
一般来说,供给SDK的厂商都会给你一份DEMO项目,或者是包括有函数定义的头文件(*.h)。你只需求按照转换规则,将头文件里边的函数签名翻译成C#版别的即可。
函数签名不正确#
有的时分,你名字直接和头文件相同还不行,得手动指定EntryPoint参数。你能够运用DLLExportViewer东西来检查DLL的所有开放函数签名,将其复制下来,填写到EntryPoint参数即可。
Copy
[DllImport(@”ThirdFilesAlprSDK.dll”,EntryPoint=”AlprSDK_Startup@12″,CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Winapi)]publicstaticexternintAlprSDK_Startup(IntPtrhNotifyWnd,uintnCommandId,stringpLocalAddress);
传递回调函数#
有时第三方SDK需求你传递回调函数,一般都只供给了一个void*定义,也便是一个函数指针。那咱们在C#怎么将委托传递给该参数作为回调函数呢?
Copy
ALPRSDK_APIOS_ErrorWINAPIAlprSDK_SearchAllCameras(unsignedintnTimeout,void*callback,char*pLocalAddr=NULL);
这个时分就需求运用到[UnmanagedFunctionPointer]特性来指定函数指针了,只需求将其标注到委托定义上,指定函数的调用方式即可。
最终我在C#里边编写的办法签名如下:
Copy
[UnmanagedFunctionPointer(CallingConvention.Winapi,CharSet=CharSet.Ansi)]publicdelegatevoidSearchAllCamerasCallback(uintdeviceType,stringdeviceName,stringdeviceIp,byte[]macAddress,ushortwPortWeb,ushortwPortListen,stringpSubMask,stringpGateway,stringpMultiAddress,stringpDnsAddress,ushortwMultiPort,intnChannelNum,intnFindCount,uintdwDeviceId);
[DllImport(@”ThirdFilesAlprSDK.dll”,EntryPoint=”_AlprSDK_SearchAllCameras@12″,CharSet=CharSet.Ansi,CallingConvention=CallingConvention.Winapi)]publicstaticexternintAlprSDK_SearchAllCameras(uintnTimeout,SearchAllCamerasCallbackcallback,stringpLocalAddress);
获取摄像头传递的位图#
原始C++的函数签名如下:
Copy
//////////////////////////////////////////////////////////////////////////////////////////////捕获一张bmp图片.//pBmpBuf:存放数据的缓冲区,传入参数时应该为NULL,内存由SDK自行办理.外面的应用程序不用去开释内存//len:数据的长度ALPRSDK_APIOS_ErrorWINAPIAlprSDK_CaptureBmp(intnHandleID,void**pBmpBuf,int*len);
首要的难点在于参数void**pbmp的翻译,这儿参数xx便是指针的指针。因为这个位图是SDK来生成的,所以它会在内存空间拓荒一段区域用于位图的存储。所以void*指向的是这个位图的开始地址,而我传递void**便是让SDK将这个开始地址传递给我。
所以void*能够翻译为IntPtr,而这个地址不是我赋值的,而是SDK给我的地址,所以咱们需求加上按引证传递关键字ref。
如此,咱们便获得了位图在内存空间的开始地址,并且办法也将这个位图的大小给了咱们。咱们只需求从开始地址读取N个字节的数据,将其转储到byte[]即可。有了byte[]目标,你就能够进行其他的操作了,例如加载,保存等。

© 版权声明
好牛新坐标
版权声明:
1、IT大王遵守相关法律法规,由于本站资源全部来源于网络程序/投稿,故资源量太大无法一一准确核实资源侵权的真实性;
2、出于传递信息之目的,故IT大王可能会误刊发损害或影响您的合法权益,请您积极与我们联系处理(所有内容不代表本站观点与立场);
3、因时间、精力有限,我们无法一一核实每一条消息的真实性,但我们会在发布之前尽最大努力来核实这些信息;
4、无论出于何种目的要求本站删除内容,您均需要提供根据国家版权局发布的示范格式
《要求删除或断开链接侵权网络内容的通知》:https://itdw.cn/ziliao/sfgs.pdf,
国家知识产权局《要求删除或断开链接侵权网络内容的通知》填写说明: http://www.ncac.gov.cn/chinacopyright/contents/12227/342400.shtml
未按照国家知识产权局格式通知一律不予处理;请按照此通知格式填写发至本站的邮箱 wl6@163.com

相关文章