Go语言so动态调用
注意事项:
- 编译的GO版本必须完全一致
- 双方依赖的公共第三方库版本必须完全一致
- GOPATH也得保持一致,这一点可以在编译时候使用trimpath参数解决
- 插件加载之后无法卸载
- 导出文件较大
goso/
├── modules/
│ └── hello/
│ └── hello.go
├── main.go
└── build.sh
- 首先创建模块代码:
如果要添加新的导出函数,需要:
- 在函数前添加 //export FunctionName 注释;
- 确保函数是可导出的(首字母大写)。
// hello.go
package main
import "C"
import "fmt"
//export SayHello
func SayHello(name string) string {
return fmt.Sprintf("你好, %s!", name)
}
//export Add
func Add(a, b int) int {
return a + b
}
// 必需的main函数
func main() {}
- 创建主程序
// main.go
package main
import (
"fmt"
"plugin"
"reflect"
)
func inspectModule(path string) {
// 加载.so文件
p, err := plugin.Open(path)
if err != nil {
fmt.Printf("加载模块失败: %v\n", err)
return
}
fmt.Printf("\n检查模块: %s\n", path)
fmt.Println("导出的符号:")
// 获取所有导出的函数
symHello, err := p.Lookup("SayHello")
if err == nil {
// 使用反射获取函数信息
t := reflect.TypeOf(symHello)
fmt.Printf("函数: SayHello\n")
fmt.Printf(" 参数: %v\n", t.String())
}
symAdd, err := p.Lookup("Add")
if err == nil {
t := reflect.TypeOf(symAdd)
fmt.Printf("函数: Add\n")
fmt.Printf(" 参数: %v\n", t.String())
}
// 测试调用
if symHello != nil {
if f, ok := symHello.(func(string) string); ok {
result := f("小明")
fmt.Printf("\n测试调用 SayHello: %s\n", result)
}
}
if symAdd != nil {
if f, ok := symAdd.(func(int, int) int); ok {
result := f(5, 3)
fmt.Printf("测试调用 Add: 5 + 3 = %d\n", result)
}
}
}
func main() {
// 扫描并检查所有.so文件
inspectModule("modules/hello.so")
}
- 创建编译脚本
#!/bin/bash
# 创建输出目录
mkdir -p modules
# 编译hello模块
echo "编译 hello 模块..."
cd modules/hello
go build -buildmode=plugin -o ../hello.so
cd ../..
echo "编译完成"
python与go互调so
python 编译的so 和go编译的so,不能相互调用。
转换成C语言形式的,利用C语言调用,才能勉强调用
- 如果需要Go和Python互操作:
- 使用CGO将Go编译为c-shared
- 或使用进程间通信(如gRPC)
- 或使用Python的ctypes调用C风格的.so
- 如果只需要Go的插件系统:
- 继续使用Go的plugin模式
- 接受较大的文件体积
- 如果需要最小的文件体积:
- 考虑使用C/C++编写动态库
- 或使用其他轻量级选项
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!