1.配置WindowsGCC
环境
1.1下载mingw
- 下载地址Releases · niXman/mingw-builds-binaries (github.com)
- i686(32位),x86_64(64位)
- msvcrt(所有Windows上都可用) ,ucrt(更适合新版windows);除非您的目标是旧版本的Windows,否则UCRT作为运行库是更好的选择,因为它的编写是为了更好地支持最新的Windows版本,并提供更好的标准一致性(将您的代码升级到通用 CRT |Microsoft学习
)
- POSIX:启用 C++11/C11 多线程功能。使libgcc依赖于libwinpthreads,因此即使你不直接调用pthreads API,你也会分发winpthreads DLL。随应用程序再分发一个 DLL 并没有错。
- win32:无 C++11 多线程功能。
我这里选择i686-13.1.0-release-posix-dwarf-ucrt-rt_v11-rev1.7z和x86_64-13.1.0-release-posix-seh-ucrt-rt_v11-rev1.7z,面向win10操作系统,并且需要std::thread
1.2将mingw添加到环境变量
- 需要哪个系统位数版本,就解压对应版本,并且将对应目录添加到添加系统变量即可
1.3 验证环境
2.创建一个golang项目编译链接c资源
2.1 内联式,直接在golang内部嵌入c语言
package main
/*
#include <stdio.h>
void SayHello() {
printf("Hello World from DLL!");
}
*/
import "C"
func main() {
C.SayHello()
}
- 但凡要引用与 c/c++ 相关的内容,写到 go 文件的头部注释里面
- 嵌套的 c/c++ 代码必须符合其语法,不与 go 一样
- import "C" 这句话要紧随,注释后,不要换行,否则报错
- go 代码中调用 c/c++ 的格式是: C.xxx(),例如 C.SayHello()
2.2导入动态库.so 或 .dll 的形式
2.2.1 使用gcc编译动态库
#include <stdio.h>
void SayHello() {
printf("Hello World from DLL!");
}
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#ifdef __cplusplus
extern "C" {
#endif
void SayHello();
#ifdef __cplusplus
}
#endif
#endif // MYLIB_H
2.2.2编译成dll
gcc -shared -o mylib.dll mylib.c
gcc -fPIC -shared -o libmylib.so mylib.c
2.2.3 验证编译后dll
#include <stdio.h>
#include "mylib.h"
int main() {
SayHello();
return 0;
}
gcc test.c mylib.dll -o test.exe
-
.\test.exe
打印 Hello World from DLL!
说明dll可用
2.2.4 golang导入dll
package main
/*
#cgo windows LDFLAGS: -L. -lmylib
#cgo linux LDFLAGS: -L. -lmylib
#include "mylib.h"
*/
import "C"
func main() {
C.SayHello()
}
- 复制
mylib.dll
和mylib.h
到golang项目根目录,即可运行
2.3 外联式,链接C源文件,而不需要预先编译为库文件
package main
/*
#cgo CFLAGS: -I./mylib
#include "mylib.c"
*/
import "C"
func main() {
C.SayHello()
}