很早就开始用cython方法,ctype方法,最近知道还有个pythonnet方法。分别说来。
根目录先放inc和lib ,分别是厂商的.h文件和.so文件。然后根据头文件写cython的声明文件wrap.pyd:
# -*- coding: UTF-8 -*-
# -*- coding: UTF-8 -*-
# cdef extern from "string.h":
# void* memcpy(void* dest, void* src,size_t count) except +
cdef extern from "HCNetSDK.h":
ctypedef int BOOL
ctypedef unsigned int DWORD
ctypedef unsigned short WORD
ctypedef unsigned short USHORT
ctypedef short SHORT
ctypedef int LONG
ctypedef unsigned char BYTE
ctypedef unsigned int UINT
ctypedef void*LPVOID
ctypedef void*HANDLE
ctypedef unsigned int*LPDWORD
ctypedef unsigned long long UINT64
ctypedef signed long long INT64
cdef enum:
SERIALNO_LEN=48
NAME_LEN=32
MACADDR_LEN=6
COMM_ALARM=0x1100 #8000报警信息主动上传
MAX_DISKNUM=16#8000设备最大硬盘数
MAX_CHANNUM=16#8000设备最大通道数
MAX_ALARMOUT=4#8000设备最大报警输出数
ctypedef struct NET_DVR_DEVICEINFO_V30:
BYTE sSerialNumber[SERIALNO_LEN]
BYTE byAlarmInPortNum
BYTE byAlarmOutPortNum
BYTE byDiskNum
BYTE byDVRType
BYTE byChanNum
BYTE byStartChan
BYTE byAudioChanNum
BYTE byIPChanNum
BYTE byZeroChanNum
BYTE byMainProto
BYTE bySubProto
BYTE bySupport
BYTE bySupport1
BYTE bySupport2
WORD wDevType
BYTE bySupport3
BYTE byMultiStreamProto
BYTE byStartDChan
BYTE byStartDTalkChan
BYTE byHighDChanNum
BYTE bySupport4
BYTE byLanguageType
BYTE byVoiceInChanNum
BYTE byStartVoiceInChanNo
BYTE bySupport5
BYTE bySupport6
BYTE byMirrorChanNum
WORD wStartMirrorChanNo
BYTE bySupport7
BYTE byRes2
ctypedef struct NET_DVR_SDKSTATE:
DWORD dwTotalLoginNum
DWORD dwTotalRealPlayNum
DWORD dwTotalPlayBackNum
DWORD dwTotalAlarmChanNum
DWORD dwTotalFormatNum
DWORD dwTotalFileSearchNum
DWORD dwTotalLogSearchNum
DWORD dwTotalSerialNum
DWORD dwTotalUpgradeNum
DWORD dwTotalVoiceComNum
DWORD dwTotalBroadCastNum
DWORD dwTotalListenNum
DWORD dwEmailTestNum
DWORD dwBackupNum
DWORD dwTotalInquestUploadNum
DWORD dwRes[6]
ctypedef NET_DVR_DEVICEINFO_V30 *LPNET_DVR_DEVICEINFO_V30
ctypedef NET_DVR_SDKSTATE *LPNET_DVR_SDKSTATE
BOOL __stdcall NET_DVR_Init() except +
BOOL __stdcall NET_DVR_Cleanup() except +
BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime, DWORD dwTryTime) except +
BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval, BOOL bEnableRecon) except +
DWORD __stdcall NET_DVR_GetLastError() except +
LONG __stdcall NET_DVR_Login_V30(char *sDVRIP, WORD wDVRPort, char *sUserName, char *sPassword, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo) except +
BOOL __stdcall NET_DVR_Logout_V30(LONG lUserID) except +
BOOL __stdcall NET_DVR_Logout(LONG lUserID) except +
BOOL NET_DVR_GetSDKState( LPNET_DVR_SDKSTATE pSDKState) except +
ctypedef struct NET_DVR_ALARMER:
BYTE byUserIDValid# userid是否有效 0-无效,1-有效 */
BYTE bySerialValid# 序列号是否有效 0-无效,1-有效 */
BYTE byVersionValid# 版本号是否有效 0-无效,1-有效 */
BYTE byDeviceNameValid# 设备名字是否有效 0-无效,1-有效 */
BYTE byMacAddrValid# MAC地址是否有效 0-无效,1-有效 */
BYTE byLinkPortValid# login端口是否有效 0-无效,1-有效 */
BYTE byDeviceIPValid# 设备IP是否有效 0-无效,1-有效 */
BYTE bySocketIPValid# socket ip是否有效 0-无效,1-有效 */
LONG lUserID# NET_DVR_Login()返回值, 布防时有效 */
BYTE sSerialNumber[SERIALNO_LEN]# /* 序列号 */
DWORD dwDeviceVersion# /* 版本信息 高16位表示主版本,低16位表示次版本*/
char sDeviceName[NAME_LEN]# /* 设备名字 */
BYTE byMacAddr[MACADDR_LEN]# /* MAC地址 */
WORD wLinkPort# link port */
char sDeviceIP[128]# /* IP地址 */
char sSocketIP[128]# /* 报警主动上传时的socket IP地址 */
BYTE byIpProtocol# /* Ip协议 0-IPV4, 1-IPV6 */
BYTE byRes1[2]
BYTE bJSONBroken# //JSON断网续传标志。0:不续传;1:续传
WORD wSocketPort
BYTE byRes2[6]
ctypedef NET_DVR_ALARMER *LPNET_DVR_ALARMER
ctypedef struct NET_DVR_ALARMINFO:
DWORD dwAlarmType#/*0-信号量报警,1-硬盘满,2-信号丢失,3-移动侦测,4-硬盘未格式化,5-读写硬盘出错,6-遮挡报警,7-制式不匹配, 8-非法访问, 9-视频信号异常,10-录像异常 11- 智能场景变化*/
DWORD dwAlarmInputNumber#/*报警输入端口*/
DWORD dwAlarmOutputNumber[MAX_ALARMOUT]#/*触发的输出端口,哪一位为1表示对应哪一个输出*/
DWORD dwAlarmRelateChannel[MAX_CHANNUM]#/*触发的录像通道,哪一位为1表示对应哪一路录像, dwAlarmRelateChannel[0]对应第1个通道*/
DWORD dwChannel[MAX_CHANNUM]#/*dwAlarmType为2或3,6,9,10时,表示哪个通道,dwChannel[0]位对应第1个通道*/
DWORD dwDiskNumber[MAX_DISKNUM]#/*dwAlarmType为1,4,5时,表示哪个硬盘, dwDiskNumber[0]位对应第1个硬盘*/
ctypedef NET_DVR_ALARMINFO *LPNET_DVR_ALARMINFO
ctypedef void (__stdcall *MSGCallBack)(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
BOOL __stdcall NET_DVR_SetDVRMessageCallBack_V30(MSGCallBack fMessageCallBack, void* pUser)
LONG __stdcall NET_DVR_StartListen_V30(char *sLocalIP, WORD wLocalPort, MSGCallBack DataCallback, void* pUserData)
BOOL __stdcall NET_DVR_StopListen_V30(LONG lListenHandle)
自己设计到底用啥,写桥梁过度文件wrap.pyx:
cimport wrap
from libc.stdlib cimport malloc, free
from libc.string cimport memcpy
from cpython.pycapsule cimport *
# cdef object callbackfunc
# cdef void __stdcall MessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser):
# cdef wrap.NET_DVR_ALARMINFO struAlarmInfo
# memcpy(&struAlarmInfo, pAlarmInfo, sizeof(wrap.NET_DVR_ALARMINFO))
# altype=struAlarmInfo.dwAlarmType
# chan=-1
# for i in range(0,17):
# if struAlarmInfo.dwChannel[i] == 1:
# chan=i+1
# break
# # 使用request 发送到sever
# global callbackfunc
# (