前言:
目前大家对“hcnetsdkdll153”可能比较珍视,兄弟们都需要剖析一些“hcnetsdkdll153”的相关文章。那么小编同时在网摘上搜集了一些关于“hcnetsdkdll153””的相关知识,希望大家能喜欢,各位老铁们快快来了解一下吧!回顾
让我们回顾一下上次的内容,test.py 文件中那6行代码实现的c++ dll加载:
import os
from ctypes import *
APP_PATH = os.path.dirname(os.path.abspath(__file__))
hcnetsdk = cdll.LoadLibrary(APP_PATH + '\\HCNetSDK.dll')
hcpreview = cdll.LoadLibrary(APP_PATH + '\\HCPreview.dll')
hcplayback = cdll.LoadLibrary(APP_PATH + '\\HCPlayBack.dll')
继续
本来想直接贴全部代码,结果头条说我的字数太多,不能发布,只能一点点按顺序贴,麻烦各位一部分一部分的拷贝了,不过这样也有利于我每贴一段,进行一定程度的代码解释备注。
库导入
接着写,我们需要导入如下的库:
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import pickle
import sys
PyQT5 是诺基亚的一套老牌的跨界面开发包,利用它我们可以轻松开发windows/linux界面应用程序。
pickle是用于配置文件读写的库,本例中用于读写IP、端口、用户名、密码等配置;
sys是系统库,我们需要在创建QT程序时用到它。
结构定义与转换
以 python 的方式来定义 c++ 结构体,我们先看一下HCNetSDK.h中的原始c++定义:
再看我们在 python 中的转换代码如下:
SERIALNO_LEN = 48 #SN length
class NET_DVR_DEVICEINFO(Structure):
_fields_ = [("sSerialNumber", c_byte * SERIALNO_LEN), #SN
("byAlarmInPortNum", c_byte), #DVR Alarm input
("byAlarmOutPortNum", c_byte), #DVR Alarm Output
("byDiskNum", c_byte), #DVR Number of Hard Disk
("byDVRType", c_byte), #DVR Type, 1: DVR 2: ATM DVR 3: DVS ......
("byChanNum", c_byte), #DVR Number of Channel
("byStartChan", c_byte) #The first Channel No. E.g. DVS- 1, DVR- 1
]
#Preview via software decoding
class NET_DVR_CLIENTINFO(Structure):
_fields_ = [("lChannel", c_long), #channel no.
("lLinkMode", c_long), #If 31st bit is 0, it means connect main stream, is 1 means sub stream. Bit 0~bit 30 are used for link mode: 0: TCP mode, 1: UDP mode, 2: Multi- play mode, 3: RTP mode,4-RTP/RTSP,5-RSTP/HTTP
("hPlayWnd", c_uint32), #the play window's handle; set NULL to disable preview
("sMultiCastIP", c_char_p), #Multicast group
("byProtoType", c_byte), #0-private protocol,1-RTSP protocol
("byRes", c_byte * 3)
]
结构体 NET_DVR_DEVICEINFO 是调用海康登录函数时需要传入的参数:
结构体 NET_DVR_CLIENTINFO 是调用海康预览函数时需要传入的参数;
这里对重要的几个参数解释一下:
lLinkMode 为0代表取主码流、为1代表取子码流;
hPlayWnd 指定你需要显示视频内容的窗口;
从上可以看出,python 直接调用 c++ dll,最大的困难在于在两个语言之间进行适当的结构体、变量类型的转换,这不仅要求你对两种语言都非常熟悉,而且还要去你对windows API 编程要熟悉,特别是 windows 基于c/c++定义的一些操作系统变量类型,比如:DWORD、WORD等,这块对于初学者来说并不是那么友好。
函数定义与转换
同样,除了结构体的转换,我们还必须完成函数的转换,让我们先看看 HCNetSDK.h 中的原始c++函数定义,如下是部分截图:
我们必须转换函数的参数为 python 能够认知的类型,所以,接下来我在 python 中定义了 HCNetSDK 这个类,来实现所有的参数转换:
class HCNetSDK:
def NET_DVR_Init(self):
return hcnetsdk.NET_DVR_Init()
def NET_DVR_SetReconnect(self, dwInterval=30000, bEnableRecon=True):
return hcnetsdk.NET_DVR_SetReconnect(dwInterval, bEnableRecon)
def NET_DVR_Login(self, sDVRIP, wDVRPort, sUserName, sPassword):
di = NET_DVR_DEVICEINFO()
pdi = byref(di)
return hcnetsdk.NET_DVR_Login(str.encode(sDVRIP), wDVRPort, str.encode(sUserName), str.encode(sPassword), pdi)
def NET_DVR_Logout(self, lUserID):
return hcnetsdk.NET_DVR_Logout(lUserID)
def NET_DVR_Cleanup(self):
return hcnetsdk.NET_DVR_Cleanup()
def NET_DVR_RealPlay(self, lUserID, lChannel, hPlayWnd):
ci = NET_DVR_CLIENTINFO()
ci.lChannel = lChannel
ci.hPlayWnd = hPlayWnd
pci = byref(ci)
return hcnetsdk.NET_DVR_RealPlay(lUserID, pci)
def NET_DVR_StopRealPlay(self, lRealHandle):
return hcnetsdk.NET_DVR_StopRealPlay(lRealHandle)
def NET_DVR_GetLastError(self):
return hcnetsdk.NET_DVR_GetLastError()
def NET_DVR_GetSDKVersion(self):
return hcnetsdk.NET_DVR_GetSDKVersion()
def NET_DVR_GetSDKBuildVersion(self):
return hcnetsdk.NET_DVR_GetSDKBuildVersion()
同样这些转换对于初学者来说不太友好,你必须理解指针、常量指针、结构指针、引用等等一些概念,因此,直接拷贝代码好了,本例只写了10个函数,如果你要扩展其他函数,可以依样画葫芦,或者有问题在评论区留言好了。
结语
由于头条篇幅的限制,我们紧接着下一篇文章继续贴代码。
标签: #hcnetsdkdll153