当前位置:   article > 正文

golang的动态库(so)生成与使用_golang so

golang so

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

目录

go文件编写

so编译命令

C语言测试程序

编译C程序


go文件编写

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

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

  1. package main
  2. /*
  3. #include <stdlib.h>
  4. */
  5. import "C"
  6. import "fmt"
  7. //export HelloWorld
  8. func HelloWorld(str *C.char) *C.char{
  9. fmt.Printf(C.GoString(str))
  10. return str
  11. }
  12. func main() {
  13. // fmt.Printf("Done\n")
  14. }

so编译命令

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

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

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

readelf -a libtest.so| grep -i hello

C语言测试程序

main.c文件

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

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

  1. #ifndef __INTERFACE_H__
  2. #define __INTERFACE_H__
  3. char* HelloWorld(char *);
  4. #endif

CMakeList.txt编写

  1. cmake_minimum_required(VERSION 2.8)
  2. project(demo)
  3. # C++11 编译
  4. set(CMAKE_BUILD_TYPE "Debug")
  5. set(CMAKE_CXX_STANDARD 11)
  6. # set(CMAKE_SHARED_LINKER_FLAGS " -L./ -Wl,-rpath=./")
  7. SET(CMAKE_INCLUDE_CURRENT_DIR ON)
  8. SET(CMAKE_CXX_STANDARD_REQUIRED ON)
  9. set( demo_SOURCE
  10. ${CMAKE_CURRENT_SOURCE_DIR}/main.c
  11. )
  12. link_directories(${PROJECT_SOURCE_DIR})
  13. SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
  14. add_executable(demo ${demo_SOURCE})
  15. target_link_libraries(demo -ltest )

编译C程序

  1. mkdir build
  2. cd build
  3. cmake ..
  4. make

运行

./demo

高级用法

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

  1. func add() (**C.char, *C.char) {
  2. //a := []string{"1111111111111111111", "222", "333"}
  3. a, err := Parsefilelist()
  4. if err != nil {
  5. fmt.Println(err)
  6. return nil, C.CString(err.Error())
  7. }
  8. count := len(a)
  9. c_count := C.int(count)
  10. //使用完请释放该内存空间,防止内存泄露
  11. cArray := C.malloc(C.size_t(c_count) * C.size_t(unsafe.Sizeof(uintptr(0))))
  12. b := (*[1024]*C.char)(cArray)
  13. for index, value := range a {
  14. b[index] = C.CString(value)
  15. }
  16. return (**C.char)(&b[0]), nil
  17. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/766883
推荐阅读
相关标签
  

闽ICP备14008679号