同事用c++写的so 文件做php组件调用加解密,由于个人不会c++却会golang
所以一直考虑通过go调用so文件今天花了点时间终于跑通了记录一下
提醒:目前Go的版本不支持链接静态共享库 c文件要进行动态共享
foo.go
==================================
// #cgo LDFLAGS: -L ./ -lfoo
// #include
// #include
// #include "foo.h"
import "C"
import "fmt“
func main() {
fmt.Println(C.count)
C.foo()
}
我们看到上面例子中通过#cgo指示符告诉go编译器链接当前目录下的libfoo共享库。C.count变量和C.foo函数的定义都在libfoo共享库中。我们来创建这个共享库:
=======================
foo.h
int count;
void foo();
=========================
foo.c
#include "foo.h"
int count = 6;
void foo() {
printf("I am
foo!\n");
}
我们首先创建一个静态共享库libfoo.a,不过在编译Go源文件时我们遇到了问题:
$> go build foo.go
# command-line-arguments
/tmp/go-build565913544/command-line-arguments.a(foo.cgo2.)(.text):
foo: not defined
foo(0): not defined
那我们来创建一个动态共享库试试:
>gcc -c foo.c
>gcc -o libfoo.so -O2 -fPIC -shared
foo.c
>go build foo.go
>./foo
./foo: error while loading shared libraries: libfoo.so:
cannot open shared obje
找不到libfoo.so文件
>cp libfoo.so /usr/lib/
>./foo
6
I am foo!
以上为实现步骤
考虑调用so 文件写了以下步骤
test so
测试动态库
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
golang项目目录,建立
==================
load_so.h
int do_test_so_func(int a,int b);
=============
load_so.c
#include "load_so.h"
#include
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;
}
================
package main
import "C"
import "fmt"
func main() {
fmt.Println("20*30=", C.do_test_so_func(20, 30))
}
===================
> gcc -shared
./test_so.c -o test_so.so
> gcc -o libload_so.so -O2 -fPIC -shared
load_so.c -ldl
-ldl 为编译参数不然的话go执行会出错
.//libload_so.so: undefined reference to `dlopen'
.//libload_so.so: undefined reference to `dlsym'
>./test
20*30= 600
参考文档
http://www.cnblogs.com/ziyouchutuwenwu/p/3657285.html
http://tonybai.com/2012/09/26/interoperability-between-go-and-c/