志在指尖
用双手敲打未来

C# 结合 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(@”ThirdFiles\AlprSDK.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(@”ThirdFiles\AlprSDK.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[]目标,你就能够进行其他的操作了,例如加载,保存等。

未经允许不得转载:IT技术网站 » C# 结合 PInvoke 对接 IP 摄像头的笔记
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载