解密C#-SQLite是如何移植的
兩周前InfoQ報道了SQLite移植到了.NET的消息。由于社區對這一項目的異常關注,為了弄清C#-SQLite移植,我們采訪了此項目的開發者Noah Hart。
你為什么要做這個項目?
我本來的目的是在程序中使用嵌入式數據庫,同時不依賴于額外的dlls。我搜索后發現了SQLite,并決定嘗試在我寫的免費程序Punjabi Kosh中使用部分SQLite數據庫引擎代碼。最初我是用VB進行移植的,但后來發現并不很合適。當時我還希望能夠同時重寫Kosh,并學習一下C#-SQLite移植,你是如何移植的,使用工具還是手工完成?
1:創建一個新的C#項目,其中只包含空的main函數,然后將所有SQLite源文件和頭文件添加進來。當然這會產生很多的錯誤信息。
2:注釋掉所有C代碼。我的想法是逐步移植,所以首先需要編譯通過。
3:由于當時我對C#并不熟悉,因此下一步是確定這兩種語言之間的不同。不出所料,這兩種語言之間的語法差異微乎其微。我可以用Visual Studio的宏來做自動替換。 :
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語的機器翻譯。
C#-SQLite移植的相關采訪內容就到這里,希望大家喜歡。
【編輯推薦】