目录
  • 思路
  • 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

          总结 

          声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。