InfoQ

InfoQ

新闻

我的书签

登录注册 以永久保存书签。

该内容已经被标记书签!

标记书签错误,请重试!

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

作者 Abel Avram 译者 王瑜珩 发布于 2009年8月20日

领域
运维 & 基础架构,
架构 & 设计,
语言 & 开发
主题
数据访问 ,
.NET ,
编程 ,
数据库 ,
SQLite

两周前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中文站编辑,ThoughtWorks咨询师,关注企业级Web开发、敏捷实践以及项目管理。

真是无比nb 发表人 Zhao Jeffrey 发表于
我也想参与 发表人 zeng yi 发表于
ADO.NET 2.0 Provider for SQLite 发表人 breeze breeze 发表于
Re: ADO.NET 2.0 Provider for SQLite 发表人 晓博 刘 发表于
Re: ADO.NET 2.0 Provider for SQLite 发表人 wang egmkang 发表于
Punjabi Kosh 连接是错的 发表人 Wei Fisher 发表于
这人好低调 发表人 Wei Fisher 发表于
希望它可以尽快发展壮大 发表人 Zhao Jeffrey 发表于
Re: 希望它可以尽快发展壮大 发表人 Jiang Nan 发表于
  1. 返回顶部

    真是无比nb

    发表人 Zhao Jeffrey

    无比nb。

  2. 返回顶部

    我也想参与

    发表人 zeng yi

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

  3. 返回顶部

    ADO.NET 2.0 Provider for SQLite

    发表人 breeze breeze

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

  4. 返回顶部

    Re: ADO.NET 2.0 Provider for SQLite

    发表人 晓博 刘

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


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

  5. 返回顶部

    Re: ADO.NET 2.0 Provider for SQLite

    发表人 wang egmkang

    这个是P/Invoke提供的Provider.

  6. 返回顶部

    Punjabi Kosh 连接是错的

    发表人 Wei Fisher

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

  7. 返回顶部

    这人好低调

    发表人 Wei Fisher

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

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

  8. 返回顶部

    希望它可以尽快发展壮大

    发表人 Zhao Jeffrey

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

  9. 返回顶部

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

    发表人 Jiang Nan

    文件格式应该是一致的