test_so.h
int test_so_func(int a,int b);
test_so.c
#include "test_so.h"
int test_so_func(int a,int b)
{
return a*b;
}
生成so
gcc -shared ./test_so.c -o test_so.so
复制so文件到Go项目目录
Go项目目录load_so.h
int do_test_so_func(int a,int b);
load_so.c
#include "load_so.h"
#include <dlfcn.h>
int do_test_so_func(int a,int b)
{
void* handle;
typedef int (*FPTR)(int,int);
handle = dlopen("./test_so.so", 1);
FPTR fptr = (FPTR)dlsym(handle, "test_so_func");
int result = (*fptr)(a,b);
return result;
}
test.go
package main
/*
#include "load_so.h"
#cgo LDFLAGS: -ldl
*/
import "C"
import "fmt"
func main() {
fmt.Println("20*30=", C.do_test_so_func(20, 30))
}
$GOPATH/src/
├── bin
├── pkg
└── src
└── test
├── go.mod
├── load_so.c
├── load_so.h
├── test
├── test.go
├── test_so.c
├── test_so.h
└── test_so.so
test目录为Go项目,里边是上述创建的所有源码文件。
$GOPATH/src/test/go buildtest
运行
$ ./test
20*30= 600
问题
1、/* */注释的代码下一行一定是import “C”,中间不能有空行
2、import "C"必须单独一行,不能和其它库一起导入
3、有人编译的时候会报错:
$ go build
# command-line-arguments
/tmp/go-build489385520/b001/_x002.o: In function `_cgo_49a6b71449ae_Cfunc_do_test_so_func':
/tmp/go-build/cgo-gcc-prolog:54: undefined reference to `do_test_so_func'
collect2: error: ld returned 1 exit status
$GOPATH/src/项目/go buildgo buildgo run .go run testgo run test.go
4、还有人报这个错:
$ go build
# test
/tmp/go-build043875804/b001/_x003.o: In function `do_test_so_func':
./load_so.c:17: undefined reference to `dlopen'
./load_so.c:18: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
cgo LDFLAGS: -ldl