C#海康威视SDK 2.0下载图片时遇到的问题

SDK源文件直接取的 "Demo实例\3- C# 开发示例\3-回放下载\NVRCsharpDemo\CHCNetSDK.cs"。因为里面没有我做项目时需要的下载图片功能,所以对该文件进行了修改。参照SDK开发文档里的 “设备网络SDK使用手册.chm”,添加了

结构体:NET_DVR_ADDRESS、NET_DVR_FIND_PICTURE_V50、NET_DVR_FACE_EXTRA_INFO、NET_DVR_PIC_EXTRA_INFO_UNION、NET_DVR_PIC_PARAM;

函数:NET_DVR_FindPicture、NET_DVR_FindNextPicture_V50、NET_DVR_GetPicture_V50、NET_DVR_GetPicture、NET_DVR_CloseFindPicture,并完善了结构体 NET_DVR_FIND_PICTURE_PARAM (不补充完整的话貌似会出现莫名其妙的错误,例如null错误)。

在调用函数 NET_DVR_GetPicture_V50 时,遇到了内存溢出问题和 "在多字节的目标代码页中,没有此Unicode字符可以映射到的字符"。然后仔细审查了函数NET_DVR_GetPicture_V50:

其c++定义为:

NET_DVR_GetPicture_V50(LONG lUserID, LPNET_DVR_PIC_PARAM lpPicParam)

结构体NET_DVR_PIC_PARAM 的c++定义为:

typedef struct tagNET_DVR_PIC_PARAM   //查找结果结构体
{
    char *pDVRFileName;  //图片名,包含\0,最大64字节
    char *pSavedFileBuf; //保存图片的缓冲区,内存外部申请释放
    DWORD dwBufLen; //缓冲区大小
    DWORD *lpdwRetLen; //实际收到的数据长度指针,不能为NULL
    NET_DVR_ADDRESS struAddr; //图片所在的地址信息,图片查找时会返回
    BYTE byRes[256];   //保留字节
}NET_DVR_PIC_PARAM, *LPNET_DVR_PIC_PARAM;

利用工具转换c#代码为:

//函数
public static extern bool NET_DVR_GetPicture_V50(Int32 lUserID, ref NET_DVR_PIC_PARAM lpPicParam);

//结构体
[StructLayoutAttribute(LayoutKind.Sequential)]
        public struct NET_DVR_PIC_PARAM
        {
            [MarshalAsAttribute(UnmanagedType.LPStr)]
            public string pDVRFileName;
            [MarshalAsAttribute(UnmanagedType.LPStr)]
            public string pSavedFileBuf;
            public uint dwBufLen;
            public IntPtr lpdwRetLen;
            public NET_DVR_ADDRESS struAddr;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes;
        }

在函数NET_DVR_GetPicture_V50调用之前,要对其参数 lpPicParam做一个初始化,在c++中是这样的;(temp就是要传入的变量)

        //初始化变量
		temp.pDVRFileName = struSavePictrue.sFileName;
		//申请内存
		temp.pSavedFileBuf = (char *)malloc(struSavePictrue.dwFileSize);
		temp.dwBufLen = struSavePictrue.dwFileSize;
		temp.struAddr = struSavePictrue.struAddr;

很明显 pSavedFileBuf 是一个指向一段内存的指针,但是在转换c#代码的时候却将其转换为了 string 类型,然后导致调用出错。(不知道这样说对不对///)在经过无数次尝试后,最终通过更改结构体定义和插入unsafe代码解决了这个问题:

修改后的结构体定义:

​
[StructLayoutAttribute(LayoutKind.Sequential)]
        unsafe public struct NET_DVR_PIC_PARAM
        {
            [MarshalAsAttribute(UnmanagedType.LPStr)]
            public string pDVRFileName;
            public char* pSavedFileBuf;
            public uint dwBufLen;
            public IntPtr lpdwRetLen;
            public NET_DVR_ADDRESS struAddr;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 256, ArraySubType = UnmanagedType.I1)]
            public byte[] byRes;
        }

​

修改后在c#中的调用:

​
​
//初始化变量
 temp.pDVRFileName = struSavePictrue.sFileName;
//申请内存
unsafe
 {
    //需要判断 (int)struSavePictrue.dwFileSize 是否大于零, 否则可能会触发内存泄漏
   temp.pSavedFileBuf = (char *)Marshal.AllocHGlobal((int)struSavePictrue.dwFileSize);
 }                                        
 temp.dwBufLen = struSavePictrue.dwFileSize;
 temp.struAddr = struSavePictrue.struAddr;

​

​

最后还要对申请的内存做释放,防止内存泄漏:

//释放内存
unsafe
{
     Marshal.FreeHGlobal((IntPtr)temp.pSavedFileBuf);
}   

仅作为一次记录,有更好的方法欢迎一起交流。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
康威(Hikvision)是一家领先的频监控设备和解决方案提供商。他们提供了一套SDK(软件开发工具包),用于开发与其设备和平台集成的应用程序。下面是使用康威SDK开发Python保存片的一般步骤: 1. 安装SDK:首先,你需要从康威官方网站下载并安装适用于Python的SDK。确保选择与你的操作系统和Python版本兼容的SDK。 2. 导入SDK模块:在Python代码中,你需要导入SDK提供的相关模块。通常,这些模块包括设备管理、像处理和网络通信等功能。 3. 连接设备:使用SDK提供的函数或方法,你可以连接到康威设备,例如网络摄像头或频录像机。你需要提供设备的IP地址、端口号、用户名和密码等信息。 4. 获取像:一旦连接到设备,你可以使用SDK提供的函数或方法获取实时像或录制频流。你可以选择从摄像头获取单帧像或连续像流。 5. 保存像:将获取到的像保存到本地文件系统中,你可以使用Python的像处理库(如OpenCV)来完成这个任务。通过指定保存路径和文件名,将像数据写入文件。 下面是一些相关问题: 1. 如何安装康威SDK? 2. 如何连接到康威设备? 3. 如何获取实时像或录制频流? 4. 如何使用Python保存像? 5. 如何处理康威设备返回的像数据? 请注意,具体的代码实现可能因SDK版本和具体需求而有所不同。建议参考康威SDK的官方文档和示例代码以获取更详细的信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值