golang动态库(so)生成与使用方法教程

 更新时间:2023年07月21日 12:03:00   作者:三雷科技  
这篇文章主要给大家介绍了关于golang动态库(so)生成与使用的相关资料,我们平时使用的动态库都是由c/c++开发最后生成的.so文件,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

前言

go语言有很多的库,在开发c语言的时候为了快速完成某些功能,可以直接通过go语言的库进行调用.那么我们将go语言开发的程序编译成so动态库文件就可以给c或者c++程序调用.

go文件编写

如果想要导出C能使用的动态库.我们需要将函数的名称编写为大写.

并且还需要添加导出注释(重要) //export HelloWorld 这个注释必须写,并且//后面不要有空格.

package main
 
/*
#include <stdlib.h>
*/
import "C"
import "fmt"
 
//export HelloWorld
func HelloWorld(str *C.char) *C.char{
	fmt.Printf(C.GoString(str))
	return str
}
 
func main() {
 
	// fmt.Printf("Done\n")
}

so编译命令

go mod init test
go mod tidy
go build -buildmode=c-shared -o libtest.so

编译成功后会自动生成libtest.so 以及 libtest.h文件

可以通过一下命令检查是否编写编译成功.

readelf -a libtest.so| grep -i hello

C语言测试程序

main.c文件

#include "libtest.h"
void main(int argc, char* argv[]) {
    char * str =  HelloWorld("asdf");
    print(str);
}

如果libtest.h文件为自动生成,我们可以自己手动编写libtest.h文件

#ifndef __INTERFACE_H__
#define __INTERFACE_H__
 
char* HelloWorld(char *);
 
#endif

CMakeList.txt编写

cmake_minimum_required(VERSION 2.8)
project(demo)
# C++11 编译
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_STANDARD 11)
# set(CMAKE_SHARED_LINKER_FLAGS " -L./ -Wl,-rpath=./")
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
 
set( demo_SOURCE
   ${CMAKE_CURRENT_SOURCE_DIR}/main.c
)
 
link_directories(${PROJECT_SOURCE_DIR})
 
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
 
add_executable(demo ${demo_SOURCE})
 
target_link_libraries(demo -ltest ) 
 

编译C程序

mkdir build
cd build
cmake ..
make

运行

./demo

高级用法

注意:go语言中申请的内存不要直接c中使用,因为go语言的内存管理是自己决定的,因此你不知道他在什么时候自动释放,因此如果需要在go语言中使用内容请使用c.malloc来申请内容返回到C语言中。C语言注意要自己调用free释放哦。

func add() (**C.char, *C.char) {
        //a := []string{"1111111111111111111", "222", "333"}
        a, err := Parsefilelist()
        if err != nil {
                fmt.Println(err)
                return nil, C.CString(err.Error())
        }
        count := len(a)
        c_count := C.int(count)
        //使用完请释放该内存空间,防止内存泄露
        cArray := C.malloc(C.size_t(c_count) * C.size_t(unsafe.Sizeof(uintptr(0))))
        b := (*[1024]*C.char)(cArray)
        for index, value := range a {
                b[index] = C.CString(value)
        }
        return (**C.char)(&b[0]), nil
}

总结

到此这篇关于golang动态库(so)生成与使用的文章就介绍到这了,更多相关golang动态库so使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言实现权重抽奖系统的项目实践

    Go语言实现权重抽奖系统的项目实践

    本文主要介绍了Go语言实现权重抽奖系统的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • grpcurl通过命令行访问gRPC服务

    grpcurl通过命令行访问gRPC服务

    这篇文章主要为大家介绍了grpcurl通过命令行访问gRPC服务示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言中io包核心接口示例详解

    Go语言中io包核心接口示例详解

    Go的io包提供了io.Reader和io.Writer接口,分别用于数据的输入和输出,下面这篇文章主要给大家介绍了关于Go语言中io包核心接口的相关资料,需要的朋友可以参考下
    2021-12-12
  • go语言规范RESTful API业务错误处理

    go语言规范RESTful API业务错误处理

    这篇文章主要为大家介绍了go语言规范RESTful API业务错误处理方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • go使用consul实现服务发现及配置共享实现详解

    go使用consul实现服务发现及配置共享实现详解

    这篇文章主要为大家介绍了go使用consul实现服务发现及配置共享实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Go语言中的反射原理解析与应用

    Go语言中的反射原理解析与应用

    反射(Reflection)是计算机科学中的一个重要概念,它允许程序在运行时检查变量和值,获取它们的类型信息,并且能够修改它们,本文将结合实际案例,详细介绍Go语言中反射的基本概念、关键函数以及使用场景,需要的朋友可以参考下
    2024-10-10
  • golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例

    golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例

    时间和日期是我们编程中经常会用到的,下面这篇文章主要给大家介绍了关于golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例,需要的朋友可以参考下
    2022-08-08
  • golang中随机数rand的使用

    golang中随机数rand的使用

    本文主要介绍了golang中随机数rand的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 使用Gorm操作Oracle数据库踩坑记录

    使用Gorm操作Oracle数据库踩坑记录

    gorm是目前用得最多的go语言orm库,本文主要介绍了使用Gorm操作Oracle数据库踩坑记录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Go语言学习教程之goroutine和通道的示例详解

    Go语言学习教程之goroutine和通道的示例详解

    这篇文章主要通过A Tour of Go中的例子进行学习,以此了解Go语言中的goroutine和通道,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-09-09

最新评论