写点什么

用 Golang 重写 rsync(2):方案的选择

  • 2022 年 6 月 07 日
  • 本文字数:1246 字

    阅读完需:约 4 分钟

当下要把一个 c 程序重写成 golang 的程序,不考虑你就是原作者,熟悉代码,直接开写之外,我认为对于一般的开发来讲,方案必须要是能够循序渐进的,这种循序渐进一是能够确保有中间步骤可以分解,例如保证编译可以随时进行,或者确保可以交叉进行测试。


所以我考察了两种方案:

第一个是用翻译器把 c 代码翻译成 go 语言。

第二个是用 cgo 一点点渗透。


C2GO

开始其实我觉得有翻译工具能够直接把 C 翻译成 Go 是很扯的事情,但是没想到这事居然还有底层逻辑:


The C code is preprocessed with clang. This generates a larger file (pp.c), but removes all the platform-specific directives and macros.

  • pp.c is parsed with the clang AST and dumps it in a colourful text format that looks like this. Apart from just parsing the C and dumping an AST, the AST contains all of the resolved information that a compiler would need (such as data types). This means that the code must compile successfully under clang for the AST to also be usable.

  • Since we have all the types in the AST it's just a matter of traversing the tree in a semi-intelligent way and producing Go. Easy, right!?

  • 这段话的意思就是先利用 Clang 工具将 C 语言的代码进行整合和预编译,生成 AST(Abstract Syntax Tree 抽象语法树?),再对这个抽象语法树进行处理,反向生成 Golang 代码。

    这样的逻辑,我觉得可行性就比较高了,语言对语言不好做,我觉得一个 Tree 对语言的反向翻译,还是有可行性的。

    这段话摘自我采用的这个开源工具:

    https://github.com/elliotchance/c2go


    后来我还看见了另外一个类似的工具,不知道有没有人注意到,Golang 的 sqlite3 库实际是个 Cgo 的作品,我从 Mac 切回 Windows 之后,倒腾这个 C 环境就费了死劲,后来我就找纯 golang 的 sqlite3 库,打算把我的 Orm 依赖改成纯 Golang sqlite3 库,找到的库的名字叫

    modernc.org/sqlite


    我对这个名字产生了兴趣,modernc?现代 c 语言?于是我查了下,这个库背后还真有一个 c2go 的工具,原理也是将 AST 翻译成 Golang 程序,库是:

    https://modernc.org/ccgo/v3

    代码仓库见cznic / ccgo · GitLab


    我自己用的是 c2go 这个工具,但是既然 ccgo 可以翻译 sqlite3,应该也是不错的,不过说起来,对于翻译 sync 这个量级的代码,用处不大,我先截个图给大家看看,具体的我们下期再讲

    上面这个图,我们可以看到翻译的内容大量涉及指针,类型转换也比较复杂,总体来讲不容易理解。


    Cgo

    因为生成代码的质量问题,所以我用工具生成了一版之后,还是回来选择了用 Cgo 慢慢迭代,这个逻辑就很简单了,我的流程如下:

    1)讲原 C 程序 main 入口包装成函数 main_wrapper()

    2)写 Golang 的 main 函数直接调用 c 的封装函数 main_wrapper()

    3)逐步将 main_wrapper()中的步骤重写到 Golang main 中。

    4)过程中保持编译和测试,确保流程和数据正确

    5)翻译过程中,涉及全局变量时,将涉及全局变量优先迁移到 Golang,在 C 中使用 setter 和 getter 函数替代原变量引用。


    这个过程复杂,缓慢,但是感觉似乎也只有这条路。


    发布于: 刚刚阅读数: 3
    用户头像

    低代码API对接+隐私计算 2022.06.06 加入

    通过低代码工具完成API对接,结合多方计算技术实现API的隐私计算。本号主要发布创业过程中的其他相关故事,技术探索。主要创业故事见知乎或微信"百家饭隐私计算"号 https://rongapi.cn

    评论

    发布
    暂无评论
    用 Golang 重写 rsync(2):方案的选择_c_百家饭隐私计算平台创业者_InfoQ写作社区