1. 导出Core包

This commit is contained in:
kunmeng
2025-02-27 11:33:07 +08:00
parent 3124c12f67
commit 666ed24e73
6 changed files with 31 additions and 31 deletions

42
Core/CallBack.go Normal file
View File

@@ -0,0 +1,42 @@
package Core
/*
#cgo CFLAGS: -I../include
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "HCNetSDK.h"
*/
import "C"
import "unsafe"
func charPtrToByteSlice(cstr *C.char, dwBufSize DWORD) []byte {
goSlice := C.GoBytes(unsafe.Pointer(cstr), C.int(dwBufSize))
return goSlice
}
var serialCallBackHooks = make(map[LONG]serialDataCallBack)
type serialDataCallBack func(lSerialHandle LONG, lChannel LONG, pRecvDataBuffer []byte, dwBufSize DWORD, pUser unsafe.Pointer)
//export fSerialDataCallBackGo
func fSerialDataCallBackGo(lSerialHandle C.LONG, lChannel C.LONG, pRecvDataBuffer *C.char, dwBufSize C.DWORD, pUser *C.void) {
callback := serialCallBackHooks[LONG(lSerialHandle)]
println(DWORD(dwBufSize))
if callback != nil {
callback(LONG(lSerialHandle), LONG(lChannel), charPtrToByteSlice(pRecvDataBuffer, DWORD(dwBufSize)), DWORD(dwBufSize), unsafe.Pointer(pUser))
}
}
var exceptionCallBackHooks = make(map[int]ExceptionCallBack)
type ExceptionCallBack func(dwType uint32, lUserID int32, lHandle int32, pUser interface{})
//export fExceptionCallBackGo
func fExceptionCallBackGo(dwType C.DWORD, lUserID C.LONG, lHandle C.LONG, pUser *C.void) {
callback := exceptionCallBackHooks[int(lUserID)]
if callback != nil {
callback(uint32(dwType), int32(lUserID), int32(lHandle), pUser)
}
}

46
Core/Type.go Normal file
View File

@@ -0,0 +1,46 @@
package Core
type DWORD uint32
type WORD uint16
type USHORT WORD
type SHORT int16
type LONG int32
type BYTE uint8
type UINT uint32
// type LPVOID void*
// type HANDLE void*
// type LPDWORD unsigned int*
type UINT64 uint64
type INT64 int64
type NET_DVR_DEVICEINFO_V30 struct {
SSerialNumber [48]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 BYTE
WDevType WORD
BySupport3 BYTE
ByMultiStreamProto BYTE
ByStartDChan BYTE
ByStartDTalkChan BYTE
ByHighDChanNum BYTE
BySupport4 BYTE
ByLanguageType BYTE
ByVoiceInChanNum BYTE
ByStartVoiceInChanNo BYTE
byMirrorChanNum BYTE
wStartMirrorChanNo WORD
}

252
Core/core.go Normal file
View File

@@ -0,0 +1,252 @@
package Core
/*
#cgo CFLAGS: -I../include
#cgo LDFLAGS: -L${SRCDIR}/../libs/x86_64 -lHCCore -lhcnetsdk -lhpr -lNPQos -lSuperRender
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "HCNetSDK.h"
extern void fSerialDataCallBackGo(LONG lSerialHandle,LONG lChannel,char *pRecvDataBuffer,DWORD dwBufSize,void *pUser);
void FSerialDataCallBackCGo(LONG lSerialHandle,LONG lChannel,char *pRecvDataBuffer,DWORD dwBufSize,void *pUser){
fSerialDataCallBackGo(lSerialHandle, lChannel, pRecvDataBuffer, dwBufSize,pUser);
};
// 异常回调函数
extern void fExceptionCallBackGo(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser);
void FExceptionCallBackCgo(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{
fExceptionCallBackGo(dwType, lUserID, lHandle, pUser);
}
*/
import "C"
import (
"math"
"unsafe"
)
// Init 初始化SDK调用其他SDK函数的前提。
func Init() error {
if C.NET_DVR_Init() != 1 {
return LastError("NET_DVR_Init")
}
return nil
}
// Cleanup 释放SDK资源在程序结束之前调用。在调用时不能同时调用其他任何SDK接口。 Init 和 Cleanup 需要配对使用,即程序里面调用多少次 Init ,退出时就需要调用多少次 Cleanup。
func Cleanup() error {
if C.NET_DVR_Cleanup() != 1 {
return LastError("NET_DVR_Cleanup")
}
return nil
}
func Login(Ip string, Port int, Username string, Password string) (LONG, NET_DVR_DEVICEINFO_V30, error) {
cIp := C.CString(Ip)
defer C.free(unsafe.Pointer(cIp))
cUsername := C.CString(Username)
defer C.free(unsafe.Pointer(cUsername))
cPassword := C.CString(Password)
defer C.free(unsafe.Pointer(cPassword))
var DeviceInfo C.NET_DVR_DEVICEINFO_V30
cUserId := C.NET_DVR_Login_V30(cIp, C.WORD(Port), cUsername, cPassword, &DeviceInfo)
if LONG(cUserId) == -1 {
return -1, NET_DVR_DEVICEINFO_V30{}, LastError("NET_DVR_Login_V30")
}
DATA := CNET_DVR_DEVICEINFO_V30ToGO(&DeviceInfo)
return LONG(cUserId), DATA, nil
}
func Logout(userId LONG) error {
if userId > -1 {
cResult := C.NET_DVR_Logout(C.LONG(userId))
if cResult != 1 {
return LastError("NET_DVR_Logout")
}
}
return nil
}
func SerialStart(UserId LONG, CallBack serialDataCallBack) (LONG, error) {
SerialStartParam := C.NET_DVR_SERIALSTART_V40{}
SerialStartParam.dwSize = C.DWORD(unsafe.Sizeof(SerialStartParam))
SerialStartParam.dwSerialType = C.DWORD(2) //1:232串口2:485串口
SerialStartParam.bySerialNum = C.BYTE(1) //串口编号设备支持多个RS232串口时有效
// 填充 byRes 字段
for i := 0; i < 255; i++ {
SerialStartParam.byRes[i] = C.BYTE(0) // 示例值,逐个赋值
}
SerialStartHandle := C.NET_DVR_SerialStart_V40(C.LONG(UserId), unsafe.Pointer(&SerialStartParam), C.LONG(unsafe.Sizeof(SerialStartParam)), C.fSerialDataCallBack(C.FSerialDataCallBackCGo), nil)
if LONG(SerialStartHandle) == -1 {
return -1, LastError("NET_DVR_SerialStart_V40")
}
serialCallBackHooks[LONG(SerialStartHandle)] = CallBack
return LONG(SerialStartHandle), nil
}
func SerialSend(lSerialHandle LONG, hexbyte []byte) error {
if C.NET_DVR_SerialSend(C.LONG(lSerialHandle), 1, (*C.char)(unsafe.Pointer(&hexbyte[0])), C.DWORD(len(hexbyte))) == C.FALSE {
return LastError("NET_DVR_SerialSend")
}
return nil
}
func SerialStop(lSerialHandle LONG) error {
if int(C.NET_DVR_SerialStop(C.LONG(lSerialHandle))) != 1 {
return LastError("SerialStop")
}
delete(serialCallBackHooks, lSerialHandle)
return nil
}
type CDVR_PTZPOS C.NET_DVR_PTZPOS
func (d *CDVR_PTZPOS) Go() DVR_PTZPOS {
return DVR_PTZPOS{
WAction: 1,
WPanPos: HEX2DEC(WORD(d.wPanPos)),
WTiltPos: HEX2DEC(WORD(d.wTiltPos)),
WZoomPos: HEX2DEC(WORD(d.wZoomPos)),
}
}
func (d *CDVR_PTZPOS) Set(Action, PanPos, TiltPos, ZoomPos float64) {
//a1 := DEC2HEX(Action)
//a2 := DEC2HEX(PanPos)
//a3 := DEC2HEX(TiltPos)
//a4 := DEC2HEX(ZoomPos)
//println(a1, a2, a3, a4)
d.wAction = C.WORD(Action)
d.wPanPos = C.WORD(DEC2HEX(PanPos))
d.wTiltPos = C.WORD(DEC2HEX(TiltPos))
d.wZoomPos = C.WORD(DEC2HEX(ZoomPos))
//d.wAction = C.WORD(1)
//d.wPanPos = C.WORD(0x77)
//d.wTiltPos = C.WORD(0x88)
//d.wZoomPos = C.WORD(0x99)
}
type DVR_PTZPOS struct {
WAction int
WPanPos float64
WTiltPos float64
WZoomPos float64
}
// DEC2HEX 将十进制浮点数转换为十六进制整数
func DEC2HEX(dec float64) WORD {
// 提取千位(对应十进制的百位)
bai := uint16(dec / math.Pow(10, 2))
dec -= float64(bai) * math.Pow(10, 2)
// 提取百位(对应十进制的十位)
shi := uint16(dec / math.Pow(10, 1))
dec -= float64(shi) * math.Pow(10, 1)
// 提取十位(对应十进制的个位)
ge := uint16(dec / math.Pow(10, 0))
dec -= float64(ge) * math.Pow(10, 0)
// 提取个位(对应十进制的十分位)
xiao := uint16(dec * 10)
// 合成十六进制数
hex := WORD(bai)<<12 | WORD(shi)<<8 | WORD(ge)<<4 | WORD(xiao)
return hex
}
// HEX2DEC 将十六进制整数转换为十进制浮点数
func HEX2DEC(hex WORD) float64 {
// 提取十六进制数的千位(对应十进制的百位)
bai := byte(hex >> 12)
hex = hex - WORD(bai)*WORD(math.Pow(16, 3))
// 提取十六进制数的百位(对应十进制的十位)
shi := byte(hex >> 8)
hex = hex - WORD(shi)*WORD(math.Pow(16, 2))
// 提取十六进制数的十位(对应十进制的个位)
ge := byte(hex >> 4)
hex = hex - WORD(ge)*WORD(math.Pow(16, 1))
// 提取十六进制数的个位(对应十进制的十分位)
xiao := byte(hex)
// 计算对应的十进制浮点数
return float64(bai)*math.Pow(10, 2) + float64(shi)*math.Pow(10, 1) + float64(ge)*math.Pow(10, 0) + float64(xiao)*math.Pow(10, -1)
}
func GetDVRConfig(lUserID LONG, dwCommand DWORD, lChannel LONG, lpOutBuffer unsafe.Pointer, dwOutBufferSize DWORD) error {
bytesReturned := C.DWORD(0)
cResult := C.NET_DVR_GetDVRConfig(C.LONG(lUserID), C.DWORD(dwCommand), C.LONG(lChannel), C.LPVOID(lpOutBuffer), C.DWORD(dwOutBufferSize), &bytesReturned)
if cResult != 1 {
return LastError("NET_DVR_GetDVRConfig")
}
return nil
}
func SetDVRConfig(lUserID LONG, dwCommand DWORD, lChannel LONG, lpInBuffer unsafe.Pointer, dwOutBufferSize DWORD) error {
cResult := C.NET_DVR_SetDVRConfig(C.LONG(lUserID), C.DWORD(dwCommand), C.LONG(lChannel), C.LPVOID(lpInBuffer), C.DWORD(dwOutBufferSize))
if cResult != 1 {
return LastError("NET_DVR_SetDVRConfig")
}
return nil
}
func LastError(funcName string) error {
cCode := C.NET_DVR_GetLastError()
if cCode == 0 {
return nil
}
var text string
if cCode == 3 {
text = "sdk not init."
} else {
cCode2 := C.LONG(cCode)
cText := C.NET_DVR_GetErrorMsg(&cCode2)
text = C.GoString(cText)
}
return NewHcnetError(int(cCode), text, funcName)
}
func PTZControlWithSpeed_Other(lUserID LONG, lChannel LONG, dwPTZCommand DWORD, dwStop DWORD, dwSpeed DWORD) error {
state := C.NET_DVR_PTZControlWithSpeed_Other(C.LONG(lUserID), C.LONG(lChannel), C.DWORD(dwPTZCommand), C.DWORD(dwStop), C.DWORD(dwSpeed))
if state == C.FALSE {
return LastError("NET_DVR_PTZControlWithSpeed_Other")
}
return nil
}
func CNET_DVR_DEVICEINFO_V30ToGO(CData *C.NET_DVR_DEVICEINFO_V30) NET_DVR_DEVICEINFO_V30 {
var goData NET_DVR_DEVICEINFO_V30
// Copy the SSerialNumber field
for i := 0; i < 48; i++ {
goData.SSerialNumber[i] = BYTE(byte(CData.sSerialNumber[i]))
}
// Copy other fields
goData.ByAlarmInPortNum = BYTE(CData.byAlarmInPortNum)
goData.ByAlarmOutPortNum = BYTE(CData.byAlarmOutPortNum)
goData.ByDiskNum = BYTE(CData.byDiskNum)
goData.ByDVRType = BYTE(CData.byDVRType)
goData.ByChanNum = BYTE(CData.byChanNum)
goData.ByStartChan = BYTE(CData.byStartChan)
goData.ByAudioChanNum = BYTE(CData.byAudioChanNum)
goData.ByIPChanNum = BYTE(CData.byIPChanNum)
goData.ByZeroChanNum = BYTE(CData.byZeroChanNum)
goData.ByMainProto = BYTE(CData.byMainProto)
goData.BySubProto = BYTE(CData.bySubProto)
goData.BySupport = BYTE(CData.bySupport)
goData.BySupport1 = BYTE(CData.bySupport1)
goData.BySupport2 = BYTE(CData.bySupport2)
goData.WDevType = WORD(CData.wDevType)
goData.BySupport3 = BYTE(CData.bySupport3)
goData.ByMultiStreamProto = BYTE(CData.byMultiStreamProto)
goData.ByStartDChan = BYTE(CData.byStartDChan)
goData.ByStartDTalkChan = BYTE(CData.byStartDTalkChan)
goData.ByHighDChanNum = BYTE(CData.byHighDChanNum)
goData.BySupport4 = BYTE(CData.bySupport4)
goData.ByLanguageType = BYTE(CData.byLanguageType)
goData.ByVoiceInChanNum = BYTE(CData.byVoiceInChanNum)
goData.ByStartVoiceInChanNo = BYTE(CData.byStartVoiceInChanNo)
return goData
}

30
Core/error.go Normal file
View File

@@ -0,0 +1,30 @@
package Core
import "C"
import (
"strconv"
)
// 构造HcnetError
func NewHcnetError(Code int, Msg string, FuncName string) *HcnetError {
return &HcnetError{Code: Code, Msg: Msg, FuncName: FuncName}
}
// 海康网络sdk自定义错误
type HcnetError struct {
Code int `json:"Code"` // 错误码
Msg string `json:"Msg"` // 错误码描述
FuncName string `json:"FuncName"`
}
func (p *HcnetError) Error() string {
return strconv.FormatInt(int64(p.Code), 10) + "," + p.Msg
}
func (p *HcnetError) IsPasswordError() bool {
return p.Code == 1
}
func (p *HcnetError) IsDeviceOfflineError() bool {
return p.Code == 7
}