海康SDK编程指南
目前使用的海康SDK包括IPC_SDK(硬件设备),Plat_SDK(平台),其中两套SDK都需单独调用海康播放库PlayCtrl.dll来解码视频流,返回视频信息和角度信息。本文仅对视频监控常用功能的使用进行说明,其它未实现功能请参看设备网络SDK使用手册和播放库编程指南V7.2。
IPC_SDK编程指南
(一) SDK的引用
由于IPC_SDK没有SDK安装程序,所以需手工把下面图表中的DLL放入Debug或者Release文件夹的根目录下供程序调用,或者加入系统环境变量Path下。
名称 |
版本号 |
说明 |
AudioIntercom.dll |
1.1.0.5 |
|
AudioRender.dll |
1.0.0.2 |
|
DsSdk.dll |
6.0.10.922 |
|
gdiplus.dll |
|
微软库 |
HCNetSDK.dll |
4.3.0.6 |
网络功能调用,大量功能调用此库 |
OpenAL32.dll |
|
|
PlayCtrl.dll |
7.2.0.0 |
播放库,定制版本,增加返角回调及数据结构 |
QosControl.dll |
1.0.0.1 |
|
StreamTransClient.dll |
1.1.2.12 |
|
SuperRender.dll |
1.0.1.0 |
|
SystemTransform.dll |
2.4.0.3 |
设备信息转发,根据播放库修改过 |
(二) C#程序调用DLL中的非托管函数方法
1. 调用外部声明方法
首先在C#语言源程序中声明外部方法,其基本形式是:
[DLLImport(“DLL文件”)]
修饰符 extern 返回变量类型 方法名称 (参数列表)
例如:
- using System.Runtime.InteropServices;
-
- [DllImport("HCNetSDK.dll")]
- public static extern bool NET_DVR_Init();
注意:
1) 需要在程序声明中使用System.Runtime.InteropServices命名空间。 DllImport只能放置在方法声明上。
2) DLL文件必须位于程序当前目录或系统定义的查询路径中(即:系统环境变量中Path所设置的路径)。
3) 返回变量类型、方法名称、参数列表一定要与DLL文件中的定义相一致。
4) 若要使用其它函数名,可以使用EntryPoint属性设置,如:[DllImport("user32.dll", EntryPoint="MessageBoxA")]
static extern int MsgBox(int hWnd, string msg, string caption, int type);
5) 其它可选的 DllImportAttribute 属性:
CharSet 指示用在入口点中的字符集,如:CharSet=CharSet.Ansi;
SetLastError 指示方法是否保留 Win32"上一错误",如:SetLastError=true;
ExactSpelling 指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配,
如:ExactSpelling=false;
PreserveSig指示方法的签名应当被保留还是被转换, 如:PreserveSig=true;
CallingConvention指示入口点的调用约定, 如:CallingConvention=CallingConvention.Winapi;
2. 参数数据类型转换
Win32 Types |
CLR Type |
char,INT8,SBYTE,CHAR |
System.SByte |
short,short int,INT16,SHORT |
System.Int16 |
int,long,long int,INT32,LONG32,BOOL,INT |
System.Int32 |
_int64,INT64,LONGLONG |
System.Int64 |
unsigned char,UINT8,UCHAR,BYTE |
System.Byte |
unsigned short,UINT16,USHORT,WORD,ATOM,WCHAR,__wchar_t |
System.UInt16 |
unsigned,unsigned int,UINT32,ULONG32,DWORD32,ULONG,DWORD,UINT |
System.UInt32 |
unsigned __int64,UINT64,DWORDLONG,ULONGLONG |
System.UInt64 |
float,FLOAT |
System.Single |
double,long double,DOUBLE |
System.Double |
BSTR |
StringBuilder |
LPCTSTR |
StringBuilder |
LPCWSTR |
IntPtr |
handle |
IntPtr |
hwnd |
IntPtr |
char * |
string |
int * |
ref int |
int & |
ref int |
void * |
IntPtrs |
unsigned char * |
ref byte |
BOOL —— |
bool |
DWORD |
uint或int |
注意:
- 指针做参数时在C#中一定要使用ref 或out关键字,尤其是结构体指针,要不会报内存读取错误
- 首先声明结构体 [StructLayoutAttribute(LayoutKind.Sequential)]
- 重写结构体的时候,之前有指明类型长度或数组长度的地方,也要进行相应的标注,要不也会导致内存错误
3. 重写结构体
例如:[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)],具体长度需参看SDK中改结构体的说明文档
或者
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 64, ArraySubType = UnmanagedType.I1)]
4. 结构体与指针之间的转换
1) 结构体转换为指针
Hik.NET_DVR_IPPARACFG_V40 ipParaCfgV40 = new Hik.NET_DVR_IPPARACFG_V40();//初始化结构体结构体
Int32 size = Marshal.SizeOf(ipParaCfgV40);//返回结构体字节数
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal(size);//定义指针字节数
Marshal.StructureToPtr(ipParaCfgV40, ptrIpParaCfgV40, false);//将结构体封装到内存指针中
//调用需要指针的方法
Marshal.FreeHGlobal(ptrIpParaCfgV40);//释放指针
2) 指针转换为结构体
Hik.NET_DVR_CAMERAPARAMCFG_EX cameraParamCfg = new Hik.NET_DVR_CAMERAPARAMCFG_EX();//实例化结构体
Int32 size = Marshal.SizeOf(cameraParamCfg );//获取结构体字节数
IntPtr ptrCfg = Marshal.AllocHGlobal(size);//为指针分配空间
//调用获取指针的方法
cameraParamCfg = (Hik.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrCfg, typeof(Hik.NET_DVR_CAMERAPARAMCFG_EX));//把指针转换为结构体
Marshal.FreeHGlobal(ptrCfg);//释放指针
3) 指针转换为结构体精简写法
Int32 size = Marshal.SizeOf(typeof(Hik.NET_DVR_PTZPOS));
IntPtr ptrPTZ = Marshal.AllocHGlobal(size);
//调用获取指针的方法
Hik.NET_DVR_PTZPOS PTZPos = (Hik.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPTZ, typeof(Hik.NET_DVR_PTZPOS));//指针转换为结构体
Marshal.FreeHGlobal(ptrPTZ);//释放指针
对第2点和第3点的说明:当一个方法的参数为一个结构体的指针时,并且执行方法后此指针会返回结构体信息时,可以有两种方式来初始化这个指针,第二种更为简洁些。
(三) SDK的调用
对IPC_SDK的C#封装类见附件Hik.cs,可参考此基础类文件进行程序功能编写。
1. 获取错误码
Hik.NET_DVR_GetLastError();//获取错误码