kaisawind's blog
  • 关于
  • 所有帖子

cgo中callback函数的实现 - Sat, Oct 24, 2020

cgo中callback函数的实现

1. 概述

cgo是连接C(not C++)和go语言的编译器,但是有很多地方需要转换。

2. callback的实现

链接库提供了函数进行回调函数赋值 HCNetSDK.h

typedef BOOL (*MSGCallBack_V31)(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);
BOOL NET_DVR_SetDVRMessageCallBack_V31(MSGCallBack_V31 fMessageCallBack, void* pUser);

需要使用C语言实现回调函数,并导出回调函数的声明,让go去实现 cfunctions.go

// Wrappers for Go callback functions to be passed into C.
package hcnet

/*
#cgo CFLAGS: -I${SRCDIR}
#include "HCNetSDK.h"

// export from go
extern BOOL MSGCallBackV31Go(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);

// WRAP 函数
BOOL MSGCallBackV31Cgo(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
	return MSGCallBackV31Go(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
}
*/
import "C"

go实现函数声明 MSGCallBackV31是函数的全局变量,在导出函数中调用全局变量。 注意export是go导出函数的实现 common.go

var MSGCallBackV31 MSGCallBackV31Func

//export MSGCallBackV31Go
func MSGCallBackV31Go(lCommand C.LONG, pAlarmer C.LPNET_DVR_ALARMER, pAlarmInfo *C.char, dwBufLen C.DWORD, pUser unsafe.Pointer) C.BOOL {
	if MSGCallBackV31 != nil {
		buffer := C.GoBytes(unsafe.Pointer(pAlarmInfo), C.int(dwBufLen))
		return C.BOOL(MSGCallBackV31(uint32(lCommand), CgoAlarmer(pAlarmer), buffer, pUser))
	}
	return TRUE
}

设置回调函数的实现 真正的回调函数赋值给了全局变量,C的注册函数注册是是cfunctions中的Cgo函数。 Cgo函数调用全局变量函数。 common.go

// SetDVRMessageCallBackV31 注册报警信息回调函数
func SetDVRMessageCallBackV31(cb MSGCallBackV31Func, pUserData unsafe.Pointer) (err error) {
	MSGCallBackV31 = cb
	ret := C.NET_DVR_SetDVRMessageCallBack_V31(C.MSGCallBack_V31(C.MSGCallBackV31Cgo), pUserData)
	if ret != TRUE {
		err = GetLastError()
		return
	}
	return
}

go中回调函数的声明 defination.go

type MSGCallBackV31Func func(lCommand uint32, pAlarmer *Alarmer, pAlarmInfo []byte, pUserData unsafe.Pointer) int32


辽ICP备2021007608号 | © 2025 | kaisawind

Facebook Twitter GitHub

▄