有些时候,使用go语言在windows上开发,需要打包成动态dll库,比如下面这段实例代码
exportgo.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package main import "C" import "fmt" //export PrintBye func PrintBye() { fmt.Println("From DLL: Bye!"); } //export Sum func Sum(a int, b int) int { return a + b; } func main() { // Need a main function to make CGO compile package as C shared library } |
test.c
1 2 3 4 5 6 7 8 9 |
#include <stdio.h> #include "exportgo.h" int main() { int a = Sum(1, 5); printf("%d\n", a); PrintBye(); return 0; } |
如果使用普通的编译命令编译
1 |
go build -buildmode=c-shared -o exportgo.dll exportgo.go |
会发现生成的文件一定会依赖一个非系统dll,libgcc_s_dw2-1.dll
这个依赖比较影响把这个dll库拿到别处去用那如何解决呢?我们知道即使是C语言,也是有运行库的,这也就意味着C语言编译出来的程序,可以动态链接运行库,也可以静态链接运行库。而我们使用的go在windows下是由gcc编译出来的,所以自然在生成dll时会依赖gcc的运行时动态链接库。知道了原因之后,就要看如何指定成静态链接了。经过不懈的尝试,发现了通过下面的命令可以让go在链接时采用静态链接运行库
1 |
go build -ldflags '-extldflags "-static"' -buildmode=c-shared -o exportgo.dll exportgo.go |
这样通过向链接器传递额外参数,就完成了静态链接gcc运行库
然后在使用dll编译最终exe的时候,也指定静态链接gcc运行时进行编译
1 |
gcc -o test test.c -static-libgcc -L. -I. -lexportgo |
同时因为使用的gcc是mingw版的,API全部是windows原生API,这样就构建了完全不依赖cygwin还有libgcc的exe和dll了~
测试回复功能是否正常