首页 > 编程语言 >使用golang编写支持C++调用的动态库,接口支持结构体和回调函数

使用golang编写支持C++调用的动态库,接口支持结构体和回调函数

时间:2023-05-11 23:00:47浏览次数:38  
标签:函数 intVal int charArray 支持 golang boolVal C++ go

网上有很多例子介绍如何使用cgo实现C/C++与golang进行接口交互。

我有个项目是使用Qt写的客户端程序,但Qt在需要使用redis、支持表单的web服务、mq或网络化日志库等需求时,往往需要加载一大堆第三方库,且编译复杂,跨平台(如Windows/linux arm/linux x86)编译时较为复杂。

鉴于有使用golang的一些经验基础,遂想以golang实现一个工具库,在需要进行功能拓展时在工具库中进行接口增加即可。

在这个过程中遇到以下2个主要问题:

    如何实现具备结构体传入和传出的接口

    如何实现具备C++设定回调函数的接口

以下是代码示例:

一、实现具备结构体传入和传出的接口

    package main
     
    /*
    #include <stdbool.h>
    #include <string.h>
    typedef struct {
        int intVal;
        bool boolVal;
        char charArray[512];
    } ParamInfo;
    typedef struct {
        int intVal;
        bool boolVal;
        char charArray[512];
    } ResultInfo;
    */
    import "C"
     
    import (
        "fmt"
        "unsafe"
    )
     
    //export calcResult
    func calcResult(paramInfoPtr *C.ParamInfo, resultInfoPtr *C.ResultInfo) C.int {
        // Convert paramInfo to Go struct
        paramInfo := &ParamInfo{
            intVal:    int(paramInfoPtr.intVal),
            boolVal:   bool(paramInfoPtr.boolVal),
            charArray: C.GoString((*C.char)(unsafe.Pointer(&paramInfoPtr.charArray))),
        }
        fmt.Printf("go print:%v\n", paramInfo)
        // Call your Go function here with paramInfo and resultInfo
        resultInfo := yourFunction(paramInfo)
     
        // Convert resultInfo from Go struct to C struct
        resultInfoPtr.intVal = C.int(resultInfo.intVal)
        resultInfoPtr.boolVal = C.bool(resultInfo.boolVal)
        copy((*[512]byte)(unsafe.Pointer(&resultInfoPtr.charArray))[:], []byte(resultInfo.charArray))
     
        return C.int(0) // Return 0 or whatever error code you want to indicate success or failure
    }
     
    type ParamInfo struct {
        intVal    int
        boolVal   bool
        charArray string
    }
     
    type ResultInfo struct {
        intVal    int
        boolVal   bool
        charArray string
    }
     
    func yourFunction(paramInfo *ParamInfo) *ResultInfo {
        // Your logic goes here
        return &ResultInfo{
            intVal:    123,
            boolVal:   true,
            charArray: "Hello, Qt!",
        }
    }
     
    func main() {
        // Do nothing, just needed for `go build` to work
    }

二、实现具备C++设定回调函数的接口

由于C++的函数定义与golang的函数定义并不一致,实现回调函数主要思路是:1. 提供接口可以根据函数原型传递回调函数指针2.回调函数指针需要在cgo代码中进行声明 3.回调的真实处理需要以go代码调用C++函数的方式进行回调。

以下两段代码 第一个是main.go文件,第二个是一个中转文件 命名为bridge.go (回调函数的声明和实现需要放到2个文件中,否则编译时会报重复定义)

main.go:

    package main
     
    /*
    #include <stdlib.h>
    typedef void ( *CallbackFunc_T )( char *, int );
    extern CallbackFunc_T pCallFuncPtr;
    extern void callBackFunc(char *str, int num);
    */
    import "C"
    import (
        "fmt"
        "unsafe"
    )
     
    //export setCallback
    func setCallback(cb C.CallbackFunc_T) {
        C.pCallFuncPtr = cb
        fmt.Println("setCallback")
    }
     
    //export triggerCallback
    func triggerCallback() {
        // 如果存在回调函数,使用提供的参数调用回调函数
        str := C.CString("Hello from Golang")
        C.callBackFunc(str, C.int(42))
        defer C.free(unsafe.Pointer(str))
    }
     
    func main() {}

bridge.go:

    package main
     
    /*
    typedef void ( *CallbackFunc_T )( char *, int );
    CallbackFunc_T pCallFuncPtr = NULL;
    void callBackFunc(char *str, int num)
    {
        if(pCallFuncPtr != NULL){
            pCallFuncPtr(str,num);
        }
    };
    */
    import "C"

golang编译输出为动态库的命令是:go build -buildmode=c-shared -o xxx.dll
————————————————
版权声明:本文为CSDN博主「橙zzzz」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/o___GRoot/article/details/129668595

标签:函数,intVal,int,charArray,支持,golang,boolVal,C++,go
From: https://www.cnblogs.com/jiftle/p/17392504.html

相关文章

  • C/C++折半查找与哈希查找[2023-05-11]
    C/C++折半查找与哈希查找[2023-05-11]4、折半查找与哈希查找(难度等级A)[问题描述]查找是通过在查找表中做比较来完成的操作。折半查找与哈希查找都是利用数组实现的查找算法。通过本题,可以观察两种查找算法的性能。一般我们用平均查找长度ASL来表示一种查找算法的性能。ASL......
  • Golang调用Dll案例
    Golang调用Dll案例前言在家办公已经两个多星期了,目前最大的困难就是网络很差。独自一个人用golang开发调用dll的驱动程序。本来就是半桶水的我,还在为等待打开一个页面而磨平了耐心。本想依葫芦画瓢把这个驱动做了。可网上找到的案例都是一些简单的调用dll。对于各种传参、获取......
  • golang调用dll,windows
    使用syscall.LoadLibrary(dllPath)函数加载dll,syscall.Syscall(...)函数调用具体的函数接口funcGoCallDll1(a,bint)uintptr{ dllFile:=syscall.NewLazyDLL(dllFileName) fmt.Println("dll:",dllFile.Name) add:=dllFile.NewProc("add") fmt.Println("......
  • 微信小程序开发工具怎样支持xdebug调试
     在做PHP项目时候用xdebug进行调试,如果使用浏览器我一般直接XdebugHelper浏览器插件。配合PHPSTORM进行调试。 微信小程序并不支持cookies,因此需要另想办法,可以在微信小程序的request里加上cookies头,如下代码所示:wx.request({url:'',header:{'Cooki......
  • c++打卡练习(25)
    回文数流程图:伪代码:源代码:#include<stdio.h>intmain(){ intm[16],n,i,t,count=0; longunsigneda,k; printf("No.numberit'ssquare(palindrome)\n"); for(n=1;n<256;n++) { k=0;t=1;a=n*n; for(i=0;a!=0;i++) { m[i]=a%10; a/=10; ......
  • 【2023 · CANN训练营第一季】TIK C++算子开发入门笔记​
    【2023·CANN训练营第一季】TIKC++算子开发入门笔记TIKC++介绍TIKC++是一种使用C/C++作为前端语言的算子开发工具,通过四层接口抽象、并行编程范式、孪生调试等技术,极大提高算子开发效率,助力AI开发者低成本完成算子开发和模型调优部署使用TIKC++开发自定义算子的优势:•C/C++原......
  • springcache + redis 配置支持缓存ttl失效
    packagetst;importcom.fasterxml.jackson.annotation.JsonAutoDetect;importcom.fasterxml.jackson.annotation.JsonTypeInfo;importcom.fasterxml.jackson.annotation.PropertyAccessor;importcom.fasterxml.jackson.databind.DeserializationFeature;importcom.......
  • C++
    复数加减(运算符重载)声明一个复数类CComplex(类私有数据成员为double型的real和image)定义构造函数,用于指定复数的实部与虚部。重载<<运算符,以格式real+imagei的格式输出当前对象(当虚部为非负数时,实部虚部中间用+号连接,当虚部为负数时,实部虚部用-号连接:如3+4i,3-4i,3+0i)。重载+运......
  • python3.11 支持TA-lib
    网上找了很多地方才找到的,以下是原网面内容分享给大家:原网址python3.11支持TA-lib-简书(jianshu.com) python3.11支持TA-libasmcos关注IP属地:北京2022.11.0316:42:52字数122阅读1,075做量化的朋友都知道Ta-lib的windows库相当难编译。python3.11性能提升......
  • 2023年高考倒计时还有几天?支持计算倒计时天数的备忘录
    进入2023年的公历5月,对于很多家里有高三学生的网友来说,未来的一个月时间要多多关注孩子的健康、学习状况了,因为一个非常重要的考试将要来临,这就是高考。今年的高考时间依旧是公历的6月7日、8日两天时间,那么今天距离高考倒计时还有几天呢?有不少学生家长想要在手机上设置每天距离高......