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

 

作者尝试使用 CGO 和 purego 工具在 Go 程序中加载动态库以实现外部数据库驱动,解决了 UDS 无法恢复状态的问题。在 Windows 和 Linux 上,该方案通过 JSON 序列化传递参数和返回值成功运行。然而,在 Mac 平台上的测试中,purego 和 plugin 均无法正常工作,前者可能由于 Go Runtime 未初始化,后者则可能是数据库驱动依赖 CGO。最终,由于 Mac 平台的障碍以及 UDS 状态同步问题,外部数据库驱动功能被取消,所有功能被合并打包。

✨ **CGO 与 purego 方案的初步尝试与成功:** 作者最初因 C 语言知识匮乏而抗拒 CGO,倾向于使用 UDS 实现外部数据库驱动。但 UDS 无法恢复进程挂掉后的状态,体验糟糕。转而调研使用 CGO 加载 Go 编译的动态库,通过 purego 工具在 Windows 和 Linux 上实现了仅暴露 4 个基础函数(DllVersion, DllOpenObj, DllCall, DllCancel),利用 JSON 序列化传递参数和返回值,解决了状态同步问题,比 UDS 更优。

🍎 **Mac 平台遇到的障碍与失败:** 在准备发布前,作者在 Mac 虚拟机上测试时发现,无论是 purego 还是 plugin 都无法成功运行 Go 编译的动态库。purego 可能存在 Go Runtime 未初始化的原因,而 plugin 则可能是因为数据库驱动依赖 CGO。这一发现使得原有的 CGO 调用动态库的方案在 Mac 平台宣告失败。

🚫 **外部数据库驱动功能的取消:** 鉴于 Mac 平台 CGO 调用动态库方案的失败,以及 UDS 固有的状态无法同步问题,作者不得不取消外部数据库驱动的功能,转而将所有功能打包到一起,以避免用户体验上的不便。

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

对于 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 动态库 purego Mac
相关文章