CGO调用海康威视SDK #
问题一:宏定义问题 #
在C语言中,extern "C"
是用于指定C++编译器按照C语言的方式进行函数名的命名规则和链接的修饰符。然而,根据您提供的错误信息,您正在使用的是C语言的编译器(gcc),而不是C++编译器。
cgo:
gcc errors for preamble:
In file included from .\hikvision.go:6:0:
error: expected identifier or '(' before string constant
#define NET_DVR_API extern "C" __declspec(dllimport)
note: in definition of macro 'NET_DVR_API'
#define NET_DVR_API extern "C" __declspec(dllimport)
^~~
添加这个:
#ifndef __cplusplus
#define NET_DVR_API
#else
#define NET_DVR_API extern "C"
#endif
原文件
#ifndef _HC_NET_SDK_H_
#define _HC_NET_SDK_H_
#ifndef _WINDOWS_
#if (defined(_WIN32) || defined(_WIN64))
#include <winsock2.h>
#include <windows.h>
#endif
#endif
#if defined(_WIN64)
#define OS_WINDOWS64 1
#endif
#if defined(__LP64__)
#define OS_POSIX64 1
#endif
#ifndef __PLAYRECT_defined
#define __PLAYRECT_defined
typedef struct __PLAYRECT
{
int x;
int y;
int uWidth;
int uHeight;
}PLAYRECT;
#endif
#if (defined(_WIN32)) //windows
//#define NET_DVR_API extern "C" __declspec(dllimport) 防止宏被重复定义 这里注释掉
typedef unsigned __int64 UINT64;
typedef signed __int64 INT64;
#elif defined(__linux__) || defined(__APPLE__) //linux
#define BOOL int
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef unsigned short USHORT;
typedef short SHORT;
typedef int LONG;
typedef unsigned char BYTE;
typedef unsigned int UINT;
typedef void* LPVOID;
typedef void* HANDLE;
typedef unsigned int* LPDWORD;
typedef unsigned long long UINT64;
typedef signed long long INT64;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define __stdcall
#define CALLBACK
#define NET_DVR_API extern "C"
typedef unsigned int COLORKEY;
typedef unsigned int COLORREF;
#ifndef __HWND_defined
#define __HWND_defined
#if defined(__APPLE__) || defined(ANDROID)
typedef void* HWND;
#elif defined(__linux__)
typedef unsigned int HWND;
#else
typedef void* HWND;
#endif
#endif
#ifndef __HDC_defined
#define __HDC_defined
#if defined(__linux__)
typedef struct __DC
{
void* surface; //SDL Surface
HWND hWnd; //HDC window handle
}DC;
typedef DC* HDC;
#else
typedef void* HDC;
#endif
#endif
typedef struct tagInitInfo
{
int uWidth;
int uHeight;
}INITINFO;
#endif
#ifndef __cplusplus
#define NET_DVR_API
#else
#define NET_DVR_API extern "C"
#endif
问题二:C语言不支持在函数参数列表中使用默认参数 #
cgo:
gcc errors for preamble:
In file included from .\hikvision.go:6:0:
C:/Users/c/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/HCNetSDK.h:51623:68: error: expected ';', ',' or ')' before '=' token
NET_DVR_API BOOL __stdcall NET_DVR_SetConnectTime(DWORD dwWaitTime = 3000, DWORD dwTryTimes = 3);
^
C:/Users/c/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/HCNetSDK.h:51624:66: error: expected ';', ',' or ')' before '=' token
NET_DVR_API BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval = 30000, BOOL bEnableRecon = TRUE);
修改方式:
NET_DVR_API BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval = 30000, BOOL bEnableRecon = TRUE);
改成这样
NET_DVR_API BOOL __stdcall NET_DVR_SetReconnect(DWORD dwInterval, BOOL bEnableRecon);
问题三:使用了一个未知的类型名 ADDITIONAL_LIB
#
error: unknown type name 'ADDITIONAL_LIB'; did you mean 'PARTITION_LDM'?
NET_DVR_API BOOL __stdcall NET_DVR_LoadAdditionalLib(ADDITIONAL_LIB libType, char const *sDllName);
^~~~~~~~~~~~~~
PARTITION_LDM
CGO不认下面这个
enum ADDITIONAL_LIB
{
PLAYCTRL = 0,
DSSDK,
STREAMCONVERT,
STREAMTRANS,
QOSSDK,
DLL_PATH_AUDIO,
EZVIZ_SSL_SDK,
ANALYZE_DATA_LIB,
DLL_LIBICONV,
SSLEAY32_SDK,
LIBEAY32_SDK,
HCNETUTILS_SDK,
NPQ_LIB,
LOAD_DLL_COUNT,
};
改成这样
typedef enum
{
PLAYCTRL = 0,
DSSDK,
STREAMCONVERT,
STREAMTRANS,
QOSSDK,
DLL_PATH_AUDIO,
EZVIZ_SSL_SDK,
ANALYZE_DATA_LIB,
DLL_LIBICONV,
SSLEAY32_SDK,
LIBEAY32_SDK,
HCNETUTILS_SDK,
NPQ_LIB,
LOAD_DLL_COUNT,
} ADDITIONAL_LIB;
CGO调用大华SDK #
问题一:宏定义问题 #
修改如下:
#ifndef DHNETSDK_H
#define DHNETSDK_H
#if (defined(_MSC_VER))
#include <windows.h>
#ifdef NETSDK_EXPORTS
#if(defined(_WIN64) || defined(WIN64))
#define CLIENT_NET_API
#else
#define CLIENT_NET_API __declspec(dllexport)
#endif
#else
#define CLIENT_NET_API __declspec(dllimport)
#endif
#define CALLBACK __stdcall
#define CALL_METHOD __stdcall ///__cdecl
#define INT64 __int64
#define TP_U64 unsigned __int64
#ifndef LLONG
#ifdef _WIN64
#define LLONG INT64
#else
#define LLONG LONG
#endif
#endif
#ifndef LDWORD
#ifdef _WIN64
#define LDWORD INT64
#else
#define LDWORD DWORD
#endif
#endif
#else ///non-windows
#define CLIENT_NET_API
#define CALL_METHOD
#define CALLBACK
#ifndef INTERNAL_COMPILE
#define RELEASE_HEADER
#endif
#ifdef RELEASE_HEADER
#define WORD unsigned short
#define DWORD unsigned int
#define LONG int
#define LPDWORD DWORD*
#ifdef __OBJC__
#include "objc/objc.h"
#else
#define BOOL int
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define BYTE unsigned char
#define UINT unsigned int
#define HDC void*
#define HWND void*
#define LPVOID void*
#ifndef NULL
#define NULL 0
#endif
#define LLONG long
#define INT64 long long
#define TP_U64 unsigned long long
#define LDWORD long
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
#ifndef DEF_RECT
///@brief rect
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;
#define DEF_RECT
#endif
#else ///�ڲ�����
#include "../../SRC/Platform/osIndependent.h"
#define INT64 int64
#define TP_U64 uint64
#endif /// RELEASE_HEADER
#endif /// linux
#ifndef LDWORD
#if (defined(WIN32) || defined(_WIN32) || defined(_WIN64))
#ifdef _WIN64
#define LDWORD __int64
#else ///WIN32
#define LDWORD DWORD
#endif
#else ///linux
#define LDWORD long
#endif
#endif
#ifdef __cplusplus
#define CLIENT_NET_API extern "C" { //改的这里
#endif
问题二:C语言不支持在函数参数列表中使用默认参数 #
C:/Users/。/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:131832:160: error: expected ';', ',' or ')' before '=' token
CLIENT_NET_API BOOL CALL_METHOD CLIENT_DelMobilePushNotify(LLONG lLoginID, const NET_MOBILE_PUSH_NOTIFY_DEL *pstuIn, NET_OUT_DELETECFG* pstuOut, int nWaitTime = 1000);
^
C:/Users/。/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:131836:143: error: expected ';', ',' or ')' before '=' token
CLIENT_NET_API BOOL CALL_METHOD CLIENT_GetMobilePushNotifyCfg(LLONG lLoginID, NET_MOBILE_PUSH_NOTIFY_CFG *pstuCfg, int *nError, int nWaitTime = 1000);
^
C:/Users/。/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:131840:164: error: expected ';', ',' or ')' before '=' token
CLIENT_NET_API BOOL CALL_METHOD CLIENT_SetMobilePushNotifyCfg(LLONG lLoginID, const NET_MOBILE_PUSH_NOTIFY_CFG *pstuCfg, int *nError, int *nRestart, int nWaitTime = 1000);
^
C:/Users/。/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:131844:167: error: expected ';', ',' or ')' before '=' token
CLIENT_NET_API BOOL CALL_METHOD CLIENT_DelMobilePushNotifyCfg(LLONG lLoginID, const NET_MOBILE_PUSH_NOTIFY_CFG_DEL *pstuIn, NET_OUT_DELETECFG* pstuOut, int nWaitTime = 1000);
除了删除没办法 跟上面一样
问题三:未定义类型 #
C:/Users/c/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:6288:5: error: unknown type name 'bool'
#ifndef DHNETSDK_H
#define DHNETSDK_H
#if (defined(WIN32) || defined(_WIN32) || defined(_WIN64))
#include <windows.h>
#ifdef NETSDK_EXPORTS
#if(defined(_WIN64) || defined(WIN64))
#define CLIENT_NET_API
#else
#define CLIENT_NET_API __declspec(dllexport)
#endif
#else
#define CLIENT_NET_API __declspec(dllimport)
#endif
#define CALLBACK __stdcall
#define CALL_METHOD __stdcall ///__cdecl
#define INT64 __int64
#define TP_U64 unsigned __int64
#define bool int //这里加了一句话
#ifndef LLONG
#ifdef _WIN64
#define LLONG INT64
#else
#define LLONG LONG
#endif
#endif
#ifndef LDWORD
#ifdef _WIN64
#define LDWORD INT64
#else
#define LDWORD DWORD
#endif
#endif
#else ///non-windows
问题四:C 语言中不能使用引用(&
)语法,这是 C++ 语言的特性
C:/Users/c/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:73691:148: error: expected ';', ',' or ')' before '&' token
typedef void (CALLBACK *fSubLogDataCallBack)(LLONG lLogHandle, NET_EM_LOG_QUERY_TYPE emLogType, const DH_DEVICE_LOG_ITEM_EX *pstuLogData, const int& nCount, LDWORD dwUser, void *reserved);
^
C:/Users/c/go/src/VideoForensic/GoldenEyes/videogoplugin/networkscan/include/dhnetsdk.h:76134:64: error: unknown type name 'fSubLogDataCallBack'; did you mean 'fLogDataCallBack'?
CLIENT_NET_API void CALL_METHOD CLIENT_SetSubscribeLogCallBack(fSubLogDataCallBack pLogDataCB, LDWORD dwUser);
^~~~~~~~~~~~~~~~~~~
fLogDataCallBack
将 const int& nCount 改为 const int* nCount,并确保正确的类型名称定义:
typedef void (CALLBACK *fSubLogDataCallBack)(LLONG lLogHandle, NET_EM_LOG_QUERY_TYPE emLogType, const DH_DEVICE_LOG_ITEM_EX *pstuLogData, const int* nCount, LDWORD dwUser, void *reserved);