Go 语言进阶实战:编写高性能 Windows DLL 动态链接库并供第三方多语言调用

我使用go写了一个http转WebSocket服务,这是一个命令行程序,双击可以直接运行,今天,有个新的需求,需要将这个命令行程序转为dll,然后供第三方使用。 1,改造程序 这个命令行程序很小,核心逻辑就是启动了一个HTTP服务,然后接收连接,然后通过WebSocket将内容转发出去。所以,在调整为dll时,仅仅需要导出两个函数即可。 1,StartServer,启动http服务,监听端口地址。因为不能阻塞,所以需要在监听服务时使用go方法启动一个携程。 2,StopServer,关闭http服务,需要提供给第三方,当它关闭时,需要调用它,释放监听地址等资源。 下面开始改造代码: package main import "C" // 必须导入 C 包 import ( // ... 原有导入 ... ) // 保持原有的全局变量和函数逻辑 (例如transDataGet, connWs 等) // 需要注意下面的//export这中间不能有空格,否则无法导出头文件 //export StartServer func StartServer() { // 将原本 main 函数里的逻辑放在这里 gin.SetMode(gin.ReleaseMode) r := gin.New() // ... 注册路由 ... r.Run("127.0.0.1:9988") } // 必须保留一个空的 main 函数 func main() {} // 其它参考StartServer,如果需要导出,一定要添加//export 2,编译命令 我是在windows环境,需要安装cgo环境,我安装了Mingw-w64支持C编译环境,执行以下命令: go build -buildmode=c-shared -o trans.dll main.go 执行后会生成trans.h和trans.dll两个文件。 3,验证dll 除了一些可以查看dll的工具外,还可以使用第三方语言进行测试。例如我这里使用Python。 import ctypes import time lib = ctypes.CDLL("./trans.dll") lib.StartServer() print("服务已在后台启动...") time.sleep(10) # 模拟第三方程序运行 lib.StopServer() print("服务已关闭") 4,再次优化代码 当实际测试的时候,我发现它会阻塞调用者,为了解决这个问题,我们需要再次改造程序。将启动服务改为非阻塞模式。将Gin的启动逻辑放入协程,并利用http.Server提供的Shutdown方法来实现优雅退出。 ...

2026-01-29 · 5 min · Eagle