QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

解密 C#-SQLite 是如何移植的

  • 2009-08-20
  • 本文字数:2112 字

    阅读完需:约 7 分钟

两周前 InfoQ 报道了 SQLite 移植到了.NET 的消息。由于社区对这一项目的异常关注,为了弄清 SQLite 是如何移植到 C#的,我们采访了此项目的开发者 Noah Hart

你为什么要做这个项目?

我本来的目的是在程序中使用嵌入式数据库,同时不依赖于额外的 dlls。我搜索后发现了 SQLite,并决定尝试在我写的免费程序 Punjabi Kosh 中使用部分 SQLite 数据库引擎代码。最初我是用 VB 进行移植的,但后来发现并不很合适。当时我还希望能够同时重写 Kosh,并学习一下 C#。

你是如何移植的,使用工具还是手工完成?

1:创建一个新的 C#项目,其中只包含空的 main 函数,然后将所有 SQLite 源文件和头文件添加进来。当然这会产生很多的错误信息。 2:注释掉所有 C 代码。我的想法是逐步移植,所以首先需要编译通过。

3:由于当时我对 C#并不熟悉,因此下一步是确定这两种语言之间的不同。不出所料,这两种语言之间的语法差异微乎其微。我可以用 Visual Studio 的宏来做自动替换。下表列出了大概的方式:

C C# -> . & ref assert Debug.Assert ==0 ==null #ifdef #if #ifndef #if !4:将所有 C 代码包装在一个 sqlite 类中。在 C 语言中,代码分布在很多文件中,并依次编译。而在 C#中,每个源文件相互独立。为了能够访问不同文件中的代码,我将每个(C 语言)文件做成 partial 类的一部分。

5:C 支持内联宏,而 C#不支持。我需要将绝大多数的#DEFINE 转换成方法或常量。
5a:确保项目仍然可以通过编译。

6:真正困难的部分才开始。我需要将所有的 struct 转换成含有公共成员的对象。
6a:确保项目仍然可以通过编译。

7: 开始清除方法上的注释。从这一步开始,工作变得有趣了。我体会到(两种语言的之间)非常多的不同,例如类定义与空指针是如何处理的、C#中没有 union、值类型和引用类型、switch case 的不同行为、byte 数组和字符串寻址。此外,我还需要一些“工具”函数,如 atoi、printf、memcpy、strcmp 等等。大多数情 况下,我只是简单的模拟它们,而不是重写代码。这是为了能节省转换的时间,确保程序可以正常工作,然后才开始用 C#的方式重写。
7a:确保项目仍然可以通过编译。

然后就是

8:while(not_done) {7; 7a;}

Hart 认为 C#-SQLite 是用 C#模拟 C,而不是移植:

C#是面向对象的,而 C 不是。因此将我的工作当成移植其实是误解,它更多的使用 C#来模拟 C。大多数代码仍然使用 C 的风格,我只用了非常非常少的对象技术和 C#特性。

整个移植过程花费了两年多一点的时间,所有的工作都是在闲暇时间里作为爱好完成的。Hart 从 106,700 行 C 代码开始,最后产生了 117,329 行 C#代码,但是

这并非是一个公平的比较,因为在很多地方我保留了 C 代码作为注释以供参考。

你觉得整个移植过程是痛苦的还是快乐的?

这是一次学习的体验,我的目的也是学习 SQLite 的工作方式,我喜欢探索程序的内部结构。

对于从 C 移植到 C#,你有什么愿意分享的么?

决定哪些部分是不需要移植的。
谨记你的目标是什么。
尽量自动化。
你的流程应该可以让你逐步移植。
看好你的指针。
提问,并真正理解问题的答案。

C#-SQLite 已经通过了超过 30,000 个测试,在这些 SQLite 的标准测试或你自己创建的测试中,有没有专门针对这个项目的?

sqlite.org 提供了标准测试,在 http://sqlite.org/faq.html 中写道:> (17)SQLite 使用全面覆盖的测试来保证质量,而不是依靠编译器警告或静态代码分析工具。换句话说,我们验证的是 SQLite 是否能产生正确的结 果,而不仅仅是满足某些代码风格。SQLite 代码中有超过三分之二是纯粹用于测试的。SQLite 测试套件有几千个独立的测试用例,其中很多测试用例还 是参数化的,因此每次发布前,都有几十万个测试调用几百万行 SQL 语句来评估(SQLite 的)正确性。

不过,所有的测试都需要 TCL 来运行,因此我还需要将 TCL 移植到 C#。我找到了一个移植到 Java 的 TCL 版本,然后我将这个版本移植到了 C#。
边注,这可是很大的工作量!

还有多少测试是没有通过的?要让它们通过还需要做多少工作?

这取决于测试是否在 C#中是必须的。例如,某些测试是与 big-endian vs. little-endian 相关的,这些测试在 C#中是不需要的。

相比于 SQLite wrapper/adapter for .NET,C#-SQLite 最大的优势是什么?

很多 SQLite wrappers/adapters for .NET 都很不错,我没有将 C#-SQLite 当成是它们的替代品。

什么样的项目可以从 C#-SQLite 中获得最大的好处?你会将它用在什么地方?

将 SQLite 引擎嵌入在程序中,而不需要额外的 dlls,可以在中等信任级别中使用完全的托管代码。

你未来的计划是什么(当然是和 C#-SQLite 相关的)?

去掉剩下的 P/Invoke 并让它可以在 Silverlight 中使用。

你会继续移植 SQLite 的后续版本么?

是的,3.6.17 已经完成了。

你计划今后如何为此项目提供支持(针对 bug 和增强)?

我建立了网站 http://code.google.com/p/csharp-sqlite/ 和一个讨论组 http://groups.google.com/group/csharp-sqlite

你需要社区的帮助么?

是的。怎么看我也不是一个 C#高手。我认为其它开发人员可以帮助提升 C#-SQLite 的性能并让它更 C#化。

Noah Hart 是一个开发人员,他的兴趣是英语到 Punjabi 语的机器翻译。

查看英文原文: Disclosing How C#-SQLite Was Ported to .NET

2009-08-20 22:193553
用户头像

发布了 63 篇内容, 共 24.9 次阅读, 收获喜欢 1 次。

关注

评论

发布
暂无评论
发现更多内容

架构第二周-学习总结

J.Smile

极客大学架构师训练营

「架构师训练营」第 2 周学习总结

guoguo 👻

极客大学架构师训练营

架构师训练营-W02H-架构设计

赤色闪电

极客大学架构师训练营

架构师训练营-第2课总结-20200613-软件设计

👑👑merlan

架构总结 软件设计

原创 | TDD工具集:JUnit、AssertJ和Mockito (二十三)编写测试-并行测试

编程道与术

Java 编程 TDD 单元测试 JUnit

架构师训练营第二周总结

Hanson

Spring BeanPostProcessor 你不能不知道的事

CoderLi

Java spring 程序员 源码分析 后端

架构师训练营 No.2 周作业

连增申

【week02】总结

chengjing

依赖倒置

陈皮

第二周总结

Thrine

JavaScript中删除树形结构数据里的节点

AR7

Java

第二周总结

LEAF

架构师训练营第2周作业

在野

极客大学架构师训练营

【week02】作业

chengjing

架构师训练营第二周作业

路人

架构师训练营第二周课后作业

竹森先生

极客大学 极客大学架构师训练营

第二周作业

LEAF

【喜迎端午】够强大,才够出“粽”,加入InfoQ写作平台,领取节日限定头像标识

InfoQ写作社区官方

写作平台 端午节 热门活动

「架构师训练营」第2周作业

fujin

ioc 极客大学架构师训练营 第二周作业

第二周 - 作业

Happy-Coming

Netty4.x的Channel相关类图及分析

娄江国

第二章总结

大雄

架构师训练营作业

Hanson

依赖倒置原则

清风明月

极客大学架构师训练营

架构师第二周课后作业

傻傻的帅

极客大学架构师训练营

无抽象不架构

菜根老谭

架构 抽象 架构思维 抽象思维

架构师训练营 第二周作业

fujin

极客大学架构师训练营

架构师训练营 - 第二周学习总结

hellohuan

极客大学架构师训练营

架构师训练营-W02S-架构设计

赤色闪电

极客大学架构师训练营

游戏夜读 | 中国移动游戏简史

game1night

解密C#-SQLite是如何移植的_.NET_Abel Avram_InfoQ精选文章