swig不能直接使用官方的程序,而必须打一个patch 后才能使用。svn下载swig源代码后(看版本号应该是2.0.5了),打上
swig_go_windows2.patch
这个patch。至于怎么打patch,请自行Google之。
swig的编译也是比较折腾的。因为他依赖 yodl2man yodl2html这东西,而这东西又依赖 icmake,不过后来发现这东西不要也行,虽然 swig在 make install的时候没有完全结束,但是生成的东西,已经够用了。
把C写的库包装为 GO包。
首先需要准备两个文件 test.i test.c
$ cat test.c #includedouble MyVar = 3.0; int Fact(int n) { if (n <= 1) return 1; else return n * Fact(n-1); } int MyMod(int x, int y) { return (x % y); } char *GetTime() { time_t ltime; time(<ime); return ctime(<ime); } $ cat test.i %module test %{ extern double MyVar; extern int Fact(int n); extern int MyMod(int x, int y); extern char *GetTime(); %} extern double MyVar; extern int Fact(int n); extern int MyMod(int x, int y); extern char *GetTime();
需要注意的是 C中的如果要想在Go中可以调用 ,首字母必须要 大写。开始 swig
//初始 $ ls test.i test.c //使用swig生成需要的文件 $ swig -go -windows test.i $ ls test.c test.go test.i test_dllmain.cxx test_gc.c test_wrap.c //分别编译 test.c test_wrap.c test_dllmain.cxx 为目标文件 *.o $ gcc -c test.c test_wrap.c test_dllmain.cxx //将上一步编译的结果链接成一个动态链接库 $ gcc -shared test.o test_wrap.o test_dllmain.o -o test.dll //编译 test.go $ 8g test.go //编译 test_gc.c $ 8c -I "go的pkg目录" test_gc.c //将test.8 test_gc.8 打包成go库,就是一个静态库,相当于gcc里面使用 ar 命令打包一样。 $ gopack grc test.a test.8 test_gc.8
至此万事俱备了。写个go 程序来试试。
$ cat main.go
package main
import "./test"
import "fmt"
func main() {
println(test.Fact(5))
//println(test.MyVar) //不能直接调用必须使用 getter setter来调用如下
test.SetMyVar(99) //来设置 MyVar的值
fmt.Printf("%f
", test.GetMyVar()) //取得刚设置的值。
println(test.MyMod(10, 3))
println(test.GetTime())
}
$ 8g main.go
$ 8l main.8
$ ./8.out.exe
120
1
Thu Jun 23 04:06:40 2011
现在把 test.dll改名,看看这个程序是不是真调用 了这个动态链接库。
如果要在其它地方使用只需要 test.a 及 test.dll 两个文件 。。test.a就是go的库,这是魔法所在,就是这样东西负责调用 C里面的函数。。因为Go是静态编译,所以编译好的Go程序就不需要 test.a这东西了,只要test.dll带上就行了。。
