思路
将 C++ 库包装成 C 库 ->
golang 通过 cgo 调用 C 库
C ++ 相关文件
目录列表
- include/
- some.h
C++ 库头文件
- some_wrapper.h
<= 用于将 C++ 库包装成 C 库的头文件
- some.h
- lib/
- libsome.a
C++ 库
- libsome.a
- src/
- some_wrapper.cpp
<= 用于将 C++ 库包装成 C 库的源码文件
- some_wrapper.cpp
源码示例
some.h
#ifndef SOME_H#define SOME_H#include #include #include namespace Some {struct DeviceInfo {std::string id;};std::vector<std::pair<std::string, std::string>> Generate(const DeviceInfo& device);}#endif// SOME_H
some_wrapper.h
#ifndef SOME_WRAPPER_H#define SOME_WRAPPER_H#ifdef __cplusplusextern "C" {#endifstruct some_item {char version[8];char value[32];};struct some_result {struct some_item data[1];int size;};int generate(struct some_result* result, char* id);#ifdef __cplusplus}#endif#endif // SOME_WRAPPER_H
some_wrapper.cpp
#include #include "some.h"#include "some_wrapper.h"#ifdef __cplusplusextern "C" {#endifint generate(struct some_result* result, char* id) {Some::DeviceInfo deviceInfo;deviceInfo.id = id;auto v = Some::Generate(deviceInfo);strcpy(result->data[0].version, v.first.data());strcpy(result->data[0].value, v.second.data());result->size = 1;return 0;}#ifdef __cplusplus}#endif
将 C++ 库包装成 C 库
# 编译生成 src/some_wrapper.o 临时目标文件g++ -c -Iinclude src/some_wrapper.cpp -o src/some_wrapper.o# 生成静态库 lib/libsomewrapper.aar -cr lib/libsomewrapper.a src/some_wrapper.o# 删除临时目标文件rm -rf src/some_wrapper.o
Golang CGO 调用 C 库
package main// #cgo CFLAGS: -I${SRCDIR}/include// #cgo LDFLAGS: -L ${SRCDIR}/lib -lsomewrapper -lsome -lstdc++// #include // #include "some_wrapper.h"import "C"import ("unsafe")type DeviceInfo struct {ID string `json:"id"`}func main() {di := DeviceInfo{ID: "123456", }cID:= C.CString(di.ID)defer C.free(unsafe.Pointer(cID))some := &C.struct_some_result{}C.generate(some, cId)if len(some.data) > 0 {item := some.data[0]version := C.GoStringN(&(item.version[0]), 8)value := C.GoStringN(&(item.value[0]), 32)result := make(map[string]string, someSize)result[version] = valuesomeSize := int(some.size)fmt.Println(result, someSize)}}
# 编译 go 文件go install -v# 运行$GOPATH/bin/demo
参考
- https://pkg.go.dev/cmd/cgo
- https://stackoverflow.com/questions/41811563/do-i-have-to-free-structs-created-with-cgo