栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

golang中采用cgo调用c++的so

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang中采用cgo调用c++的so

golang中采用cgo调用c++的so
背景

基于arm平台的生鲜识别系统,采用了go语言做为边缘端业务逻辑语言,其中调用识别模型so库来实现推理(so调用jetson nano cuda)将返回结果进行业务处理。在生鲜场景已运用成熟,当向零食识别集成时,若采用单一模型,也就是在原有模型的基础上,增加零食数据训练出来的大模型,生鲜的识别将受影响,所以,诞生了生鲜与零食两个模型的想法。

技术实现

go调用c++的so,需要通过c来调用,网上有关于cgo的使用方法,介绍篇幅非常有限,特别是对so的调用。最难的是在于复杂类型的转换,golang与c++中的类型,哪怕是常见的int、char、指针等,因两种语言定义不同,为so的集成增添了难度,经过一段时间的摸索,终于将功能实现。

那么go中如何调用so库呢?C++写的libxxxx.so库,golang中集成时,需定义出so中函数的头文件,在go文件中引用,并描述so的名称,就可以调用so中的函数了。接下来,我们由简入深吧!

golang中直接调用c
// go的源代码中直接声明C代码,比较简单的应用情况 可以直接使用这种方法 C代码直接写在 go 代码的注释中 注释之后紧跟import "C" 通过C.xx来引用C的结构和函数

package main


import "C"
import (
    "fmt"
    "sync"
)

func main() {
    var ctx *C.ctx = C.createCtx(100)
    fmt.Printf("id : %dn", ctx.id)
}

参考:https://www.codercto.com/a/39274.html,其中也有直接调用c++的示例

golang中调用so库 - 定义头文件,描述so中的函数
#ifndef F1_INFERENCE_API_H
#define F1_INFERENCE_API_H

#ifdef __cplusplus
extern "C" {
#endif

char* get_version();
int process(const unsigned char *data, int length, int num, float *result);

#ifdef __cplusplus
}
#endif
#endif //F1_INFERENCE_API_H
- 将libxxxx.so放到指定的目录中
cp libxxxx.so ~/.local/lib/
- golang中的调用 - 编译go代码
export GODEBUG=cgocheck=0
export LD_LIBRARY_PATH=:/home/f1/.local/lib;
export LIBRARY_PATH=:/home/f1/.local/lib; 
CGO_ENABLED=1 GOOS=linux go build main.go
golang与c++中类型转换
- c++中的long long类型
    Golang 中采用C.longlong(t)来转换

- c++中的float数组
    var scores [2]float32
    scores[0] = 0.8
    scores[1] = 0.9
    // 调用:入参
    C.test_float((*C.float)(unsafe.Pointer(&scores[0])))

- c++中的字符串
    Golang 中对应的类型与赋值
    var path *C.char
    path = C.CString("/home/f1/ailog.log")

- c++中的字符数组
    Golang 中对应的类型与赋值
    var names [8]*C.char
    names[0] = C.CString("苹果")
    names[1] = C.CString("大白菜")
    输入参数时需转换为**char类型
    C.test_chararray((**C.char)(unsafe.Pointer(&sku[0])))

- c++中**char转golang切片[]string
    //char** 转化成 []string
    list := C.getStringArray()
    var str []string
    var pbuf []*C.char
    header := (*reflect.SliceHeader)(unsafe.Pointer(&pbuf))
    header.Cap = 3
    header.Len = 3
    header.Data = uintptr(unsafe.Pointer(list))
    for _, i := range pbuf {
        str = append(str, C.GoString(i))
    }
    fmt.Println(str)

    //[]string 转化成 char**
    box := []string{"xing", "jack", "john"}
    var buf []*C.char
    for i, _ := range box {
        buf = append(buf, (*C.char)(unsafe.Pointer(C.CString(box[i]))))
    }
    box2 := (**C.char)(unsafe.Pointer(&buf[0]))

    参考:https://www.zhihu.com/question/27168644

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/909272.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号