1、头文件不能有任何注释(// 与/**/)
2、头文件中的结构体,如果在 go 中用到,需要在头文件中修改相应的结构体: struct 后面加上 tag结构体名 ,如下:
// 修改前
typedef struct
{
BYTE sUserName[NAME_LEN];
BYTE sPassword[PASSWD_LEN];
}NET_DVR_OPERATE_USER, *LPNET_DVR_OPERATE_USER;
// 修改后
typedef struct tagNET_DVR_OPERATE_USER
{
BYTE sUserName[NAME_LEN];
BYTE sPassword[PASSWD_LEN];
}NET_DVR_OPERATE_USER, *LPNET_DVR_OPERATE_USER;
3、头文件中回调函数不能有 CALLBACK, 如下:
// 头文件
// 修改前
typedef void(CALLBACK *fSearchDBCallBack)(LONG lHandle, DWORD dwType);
// 修改后
typedef void(*fSearchDBCallBack)(LONG lHandle, DWORD dwType);
4、数据类型转换
// go字符串转换为c字符串指针 go string --> c char*
c_char_pointer_ip := C.CString(addr)
defer C.free(unsafe.Pointer(c_char_pointer_ip))
// go字符串转换为c字符数组 go string --> c char[]
c_char_list_addr := [C.NET_DVR_DEV_ADDRESS_MAX_LEN]C.char{}
for i := 0; i < len(addr); i++ {
c_char_list_addr[i] = C.char(addr[i])
}
// c字符串指针转换为 go 字符串 c char* --> go string
name := C.GoString((*C.char)(unsafe.Pointer(&Name[0])))
// go中是用空指针作为参数 void*
unsafe.Pointer(nil)
// 调用c的结构体
var client_info C.NET_DVR_CLIENTINFO
// go中不指定回调函数,将回调函数设置为空
CallBackFunc := [0]byte{}
lRealPlayHandle := C.NET_DVR_RealPlay_V30(
C.LONG(lUserID),
(*C.NET_DVR_CLIENTINFO)(unsafe.Pointer(&client_info)),
&CallBackFunc,
unsafe.Pointer(nil),
C.FALSE)
5、go中实现回调函数
// 1、定义回调函数
/*
#include 头文件
extern void CgofSearchDBCallBack(LONG ,DWORD);
*/
import "C"
// 2、实现回调函数
//export CgofSearchDBCallBack
func CgofSearchDBCallBack(lHandle C.LONG, dwType C.DWORD){
// 回调函数的具体实现
}
// 3、调用回调函数
result := C.NET_DVR_SetfSearchDBCallBackEx(
C.LONG(lRealHandle),
C.fSearchDBCallBack(C.CgofSearchDBCallBack),
unsafe.Pointer(nil))