C/C++调用Golang二
《C/C++调用Golang一》简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用。本文总结具体项目中的使用场景,将介绍三种较复杂的调用方式:一,C++向golang传入复杂结构体;二,C++向golang传入回调函数,在golang中调用C++函数;三,C++调用golang函数,返回复杂的结构体。
(本文后面涉及三个例子,省略了编译步骤,仅展示关键代码。具体操作步骤参考《C/C++调用Golang一》)
一 C++向golang传入复杂结构体
采用avro来序列化与反序列化结构体。C++版avro使用官方版本,golang版avro使用gopkg.in/alanctgardner/gogen-avro.v4。(C++代码省略了avro结构体的序列化与反序列化,仅展示C++与Golang的交互部分)
1.1 Golang 代码
package main
import "C"
import "fmt"
//export WriteData
func WriteData(data []byte) int {
fmt.Println("WriteData ", data, len(data))
return 0
}
func main() {
}
编译生成的头文件
/* Created by "go tool cgo" - DO NOT EDIT. */
/* package c_references_to_go/sample1 */
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt32 GoInt;
typedef GoUint32 GoUint;
//typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
//typedef float _Complex GoComplex64;
//typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_32_bit_pointer_matching_GoInt[sizeof(void*)==32/8 ? 1:-1];
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern GoInt WriteData(GoSlice p0);
#ifdef __cplusplus
}
#endif
1.2 C++代码
#include
#include
#include "sample1.h"
//#include "LargeStruct.h"
typedef GoInt (*funcPtrWriteData)(GoSlice p0);
int main(){
HMODULE h = LoadLibraryA("sample1.dll");
if (NULL == h || INVALID_HANDLE_VALUE == h)
{
return -1;
}
funcPtrWriteData pfWriteData = (funcPtrWriteData)GetProcAddress(h,"