V2EX 07月25日 14:05
[Go 编程语言] 关于 Golang 加载动态库的调研报告
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章作者在为Go项目寻找外部数据库驱动实现方案时,最初考虑使用UDS,但因其不可恢复性而放弃。转而尝试CGO加载Go编译的动态库,并在Windows和Linux上通过purego成功实现。然而,在Mac平台上,purego和plugin方案均告失败,前者疑似Go Runtime未初始化,后者则因数据库驱动依赖CGO。这一结果导致作者不得不放弃外部数据库驱动功能,将所有内容打包。UDS的状态同步问题也限制了其应用,使得项目进展受挫。

🧐 **外部数据库驱动方案探索遇阻**:作者最初尝试使用Unix Domain Socket (UDS) 实现外部数据库驱动,但因UDS的不可恢复性(进程挂了重启后状态无法对应)以及可能导致的用户体验不佳(强制关闭UI)而放弃。

💻 **CGO调用Go动态库在类Unix系统上可行**:作者转而调研使用CGO加载Go编译的动态库,并成功在Windows和Linux系统上通过`purego`库实现了这一目标。该方案通过传递`uintptr`类型的参数,利用JSON序列化进行数据传递,解决了UDS的状态同步问题。

🍎 **Mac平台CGO调用Go动态库方案失败**:在Mac平台上进行测试时,作者发现无论是使用`purego`还是`plugin`方案都无法成功运行由Go编译的动态库。`purego`可能存在Go Runtime未初始化的原因,而`plugin`方案则可能因为数据库驱动依赖CGO而失败。

📉 **项目功能受限,回归单体打包**:由于在Mac平台上无法实现外部数据库驱动,作者只能取消此功能,将所有内容打包到一起,项目进展受到限制,未能实现预期的模块化和外部化设计。

至少目前来说此路不通……

对于 C 的了解仅限于 Hello World ,链接、符号什么的一无所知,所以其实一开始就是抗拒 CGO 的,打算的就是使用 UDS 来实现外部的数据库驱动。但是数据库驱动的 Rows 和 Tx 都是不可恢复对象,如果进程挂了,即使重启之后状态也都对应不上,此时只能强行关闭相关的 UI 。——这体验也太糟糕了。

所以开始调研使用 CGO 来加载由 Go 编译的动态库。在 github 的 issues 里有一些关于这方面的讨论,都是说不可行。但是看到了 purego ,尝试之后发现真的可以工作! windows 和 linux 上都没有问题。实现方式是,仅暴露了 4 个函数,DllVersion, DllOpenObj, DllCallDllCancel,传递的参数都是 uintptr,且没有返回值。返回值的内存由主程序生成,当作参数传递,然后 Dll 里面使用 JSON 序列化后写入。——至少在 windows/linux 上这么做是可以的。虽然需要序列化,但是还是要比通过 UDS 来做要好。

我没有 Mac 的设备,但是我觉得 linux 都没有问题,那应该也没事。

我做好了 Dll 的加载和简单的管理,在准备发布前的测试时,我使用 quckemu 成功的运行了 MacOs 的虚拟机。却发现在 Mac 上不论是 purego 还是 plgin 都不能成功的运行由 Go 编译的动态库。purego 可能是 dll 内部的 Go Runtime 没有初始化,plugin 可能是数据库的驱动是依赖 CGO 的缘故。

总之,我很失望,至少目前来说此路不通……

UDS 又有状态不能同步的问题,所以只能取消外部数据库驱动这个功能,全部都打包到一起了……😓

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

CGO Go动态库 Mac平台 数据库驱动 purego
相关文章