目录
- 思路
- C ++ 相关文件
- 目录列表
- 源码示例
- some.h
- some_wrapper.h
- some_wrapper.cpp
- 将 C++ 库包装成 C 库
- Golang CGO 调用 C 库
- 参考
- 总结
思路
将 C++ 库包装成 C 库 -> golang 通过 cgo 调用 C 库
C ++ 相关文件
目录列表
- include/
- some.h C++ 库头文件
- some_wrapper.h <= 用于将 C++ 库包装成 C 库的头文件
- lib/
- libsome.a C++ 库
- src/
- some_wrapper.cpp <= 用于将 C++ 库包装成 C 库的源码文件
源码示例
some.h
#ifndef SOME_H #define SOME_H #include <string> #include <utility> #include <vector> 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 __cplusplus extern "C" { #endif struct 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 <string.h> #include "some.h" #include "some_wrapper.h" #ifdef __cplusplus extern "C" { #endif int 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.a ar -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 <stdlib.h> // #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] = value someSize := 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
总结
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
评论(0)