BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

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

| 作者 Abel Avram 关注 11 他的粉丝 ,译者 王瑜珩 关注 0 他的粉丝 发布于 2009年8月22日. 估计阅读时间: 7 分钟 | AICon 关注机器学习、计算机视觉、NLP、自动驾驶等20+AI热点技术和最新落地成功案例。

两周前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

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

真是无比nb by Jeffrey Zhao

无比nb。

我也想参与 by zeng yi

我要是能够参与这个移植过程,做点贡献就好了。

ADO.NET 2.0 Provider for SQLite by breeze breeze

是否和这个的工作是相同的呢?
sourceforge.net/projects/sqlite-dotnet2/

Re: ADO.NET 2.0 Provider for SQLite by 晓博 刘

是否和这个的工作是相同的呢?
sourceforge.net/projects/sqlite-dotnet2/


不相同吧,一个是写了个Provider,一个是NB的把人家C代码改成C#的了……太有想法……

Re: ADO.NET 2.0 Provider for SQLite by wang egmkang

这个是P/Invoke提供的Provider.

Punjabi Kosh 连接是错的 by Wei Fisher

Punjabi Kosh 连接是错的,后面多个空格。请编辑 review 一下。

这人好低调 by Wei Fisher

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

我怎么看他都是一个c#高手……

希望它可以尽快发展壮大 by Jeffrey Zhao

我目前还不敢用它,还是用System.Data.SQLite了。
还有不知道它的文件和SQLite是否完全一致。

Re: 希望它可以尽快发展壮大 by Jiang Nan

文件格式应该是一致的

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

9 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT