不能。Go 默认不生成传统动态库,但可通过-buildmode=c-shared生成C ABI兼容的.so或.dll供外部调用,需满足main包、//export注释、C兼容类型等硬性条件。

Go 能否直接生成 .so 或 .dll?
不能。Go 默认编译出的是静态链接的可执行文件或归档(.a),不生成传统意义上的动态链接库(.so / .dll)。但 Go 支持 buildmode=c-shared,能导出 C 兼容的符号,生成带封装层的 .so(Linux/macOS)或 .dll(Windows),供 C/C++/Python 等调用——这本质是「C ABI 兼容的共享库」,不是 Go 原生动态模块。
使用 buildmode=c-shared 的硬性前提
必须满足以下全部条件,否则编译失败或运行时崩溃:
-
main包必须存在,且入口函数为main()(哪怕空实现) - 所有导出函数必须以大写字母开头,并用
//export FuncName注释标记 - 函数签名只能含 C 兼容类型:如
*C.char、C.int、C.size_t,不能出现string、slice、struct(除非手动转成 C 内存布局) - 不能调用 Go 运行时依赖线程本地存储的功能(如
net/http、time.Sleep),否则在多线程 C 环境中可能死锁或 panic
Linux/macOS 下生成 .so 的典型流程
假设有一个 lib.go:
package main
<p>/*</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">go语言免费学习笔记(深入)</a>”;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill6460" title="Golang Naming"><img
src="https://img.php.cn/upload/skill/000/000/081/179094616043400.jpg" alt="Golang Naming" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill6460" title="Golang Naming">Golang Naming</a>
<p>Go(Golang)命名规范 — 包括包、构造函数、结构体、接口、常量、枚举、错误、布尔值、接收器、getter/setter、函数等。</p>
</div>
<a href="/xiazai/skill6460" title="Golang Naming" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><h1>include <stdlib.h></h1><p>*/
import "C"
import "unsafe"</p><p>//export Add
func Add(a, b C.int) C.int {
return a + b
}</p><p>//export GoString
func GoString(s <em>C.char) </em>C.char {
goStr := C.GoString(s)
return C.CString("hello, " + goStr)
}</p><p>func main() {} // 必须有,但可为空
执行:
GOOS=linux GOARCH=amd64 go build -buildmode=c-shared -o libmath.so lib.go
会输出 libmath.so 和 libmath.h。注意:.h 是自动生成的头文件,声明了导出函数原型,C 端必须包含它;.so 本身依赖 libc 和 Go 运行时(libgo.so 不打包进去),所以部署时需确保目标系统有对应 Go 版本的运行时,或改用 -ldflags="-linkmode external -extldflags '-static'"(效果有限,不推荐)。
Windows 下生成 .dll 的关键差异
命令类似,但行为更敏感:
- 必须用
GOOS=windows GOARCH=amd64 go build -buildmode=c-shared -o libmath.dll lib.go - 生成的
.dll依赖libgcc和libwinpthread(MinGW 工具链),若目标机器无 MinGW 运行时,会报错The code execution cannot proceed because libwinpthread-1.dll was not found - 导出函数在 Windows 上默认不带
__declspec(dllexport),但c-shared模式已自动处理,无需手动加 - Go 1.21+ 在 Windows 上对
c-shared的栈分裂支持仍有问题,避免在导出函数中触发 goroutine 创建(比如调用http.Get)
跨平台发布时,别指望一个 .so 文件能在 Windows 上加载,也别指望 .dll 能被 Linux dlopen —— ABI 和加载器完全不同,这是操作系统层面的隔离,不是 Go 能绕过的。


















