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

相关推荐

  1. golang 通过 cgo 调用 C++

    2024-02-07 09:52:01       54 阅读
  2. c#程序调用c++开发dll

    2024-02-07 09:52:01       30 阅读
  3. 2312d,d调用中文C++

    2024-02-07 09:52:01       66 阅读
  4. c++通过serial进行上下位机通信

    2024-02-07 09:52:01       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-07 09:52:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-07 09:52:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-07 09:52:01       82 阅读
  4. Python语言-面向对象

    2024-02-07 09:52:01       91 阅读

热门阅读

  1. django密码管理器(创建项目)

    2024-02-07 09:52:01       47 阅读
  2. LeetCode 打家劫舍

    2024-02-07 09:52:01       49 阅读
  3. PyTorch 中音频信号处理库torchaudio的详细介绍

    2024-02-07 09:52:01       40 阅读
  4. Android 判断通知是进度条通知

    2024-02-07 09:52:01       43 阅读
  5. hive 创建表 字段类型

    2024-02-07 09:52:01       47 阅读
  6. 对于协同过滤算法我自己的一些总结和看法

    2024-02-07 09:52:01       52 阅读
  7. C语言 可变参数列表及相关宏

    2024-02-07 09:52:01       50 阅读