2009 年 02 月 的封存

2009開年動動腦!

在2009的大年初一終於去了花蓮一遊,應該有2, 3年沒有到花蓮了吧,當我走在海岸路之際乾涸許久的心靈仿佛立刻久旱逢甘霖,滋潤了起來,連腦筋似乎都活絡了起來。隔天騎著自行車沿著海岸路一路南行的路程中,封塵已久的思緒也逐漸的脫繭而出,回想這1,2年的變化可真大啊,不但在我個人的小世界中工作劇烈的改變中,世界的經濟狀況的變化更是令人瞠目結舌,對於5年級世代的人來說,在40多歲遇上這些巨大的衝擊應該是相當大的打擊吧。

回想這幾年來,從Borland,到DevCo,CodeGear最後到Embarcadero,我個人認為C++Builder,Delphi和JBuilder的未來似乎已經漸入佳境,為什麼? 因為:

  • 第1,    2008年底Borland傳來非常不好的訊息,整個公司巨幅虧損不說,CEO等高階主管相繼離職,看來Borland出售開發工具之後不但沒有轉運,反而愈來愈糟糕,更證實了數年前 Borland決定放棄開發工具走向ALM是嚴重的錯誤,C++Builder,Delphi和JBuilder能夠離開Borland是最好的結果。
  • 第2,    在2009年年初Embarcadero邀請我去舊金山參加全球大會,在Embarcadero的全球大會上我終於聽到了類似早年Borland全球大會的良好慣例,Embarcadero的CEO除了在銷售方面的強調之外,更強調了產品和品質的重要性,整個Embarcadero的全球大會也提供了許多產品和技術方面的訓練,而不像後期的Borland全球大會,Borland CEO只有滿嘴的空談和股票經,根本沒有公司和產品的發展計劃,整個Borland全球大會只有銷售訓練,產品和技術的內容一點都沒有。因此我在Embarcadero的全球大會上看到了C++Builder,Delphi和JBuilder在Embarcadero將有完全不一樣的未來。
  • 第3,    全世界經濟狀況的改變讓許多人瞭解到簡單,好用的東西是最好的,因此許多人從昂貴的Java/.NET世界回到了原生Win32的開發世界中,準備迎接足夠未來數年使用的原生Win64開發平台的到來,這給了C++Builder,Delphi一個絕好的機會,因為原生Win64開發正是C++Builder,Delphi未來的發展道路。
  • 第4,    這正是我想深入一點討論的內容,從許多跡象分析中可以發覺C++Builder,Delphi和JBuilder正在進行巨大的發展中,這些變化將帶來重大的改變,也將會激勵Win32和Win64開發工具的市場,對於C++Builder,Delphi和JBuilder的開發人員來說也將會覺得振奮不已。那麼C++Builder,Delphi和JBuilder會什麼樣的巨大改變呢? 讓我們一一的從一些蛛絲馬跡中分析一下,順便做為2009開年的腦筋體操,其實這些分析正是當我在花蓮海岸路一邊騎自行車一邊思考的結果。

首先我們知道從2年前開始DevCo和CodeGear便一直有公佈C++Builder,Delphi和JBuilder的發展路線圖,雖然後來DevCo和CodeGear的命運坎坷,以致C++Builder,Delphi和JBuilder的發展路線圖不斷的延後和改變,但在C++Builder,Delphi和JBuilder最終進入Embarcadero之後C++Builder,Delphi和JBuilder的發展路線也終於開始穩定下來。在前一陣子Delphi的產品經理Nick Hodges寫了一篇有關未來Delphi編譯器的文章:

http://dn.codegear.com/article/39174

在這篇文章中Nick說明了Delphi編譯器的歷史以及Delphi編譯器即將發展的方向,在其中Nick說Delphi64位元的編譯器將在2010年中才大概會準備好,因此合理的判斷Delphi 64最早應該會在2010底或是2011年初才可能出現,那麼在2009年C++Builder和Delphi會做什麼呢? 這也得從為什麼原生Delphi 64會從2009年底延遲到2010或2011年分析起。

在Nick的文章中說明了,CodeGear因為決定為C++Builder和Delphi開發一個共同的後端編譯器(Compiler Back End),因此延遲了原生BCB 64和Delphi 64,所謂共同的後端編譯器是指BCB 64和Delphi 64將使用一個共用的最佳化和機械程式碼產生器,如此一來不但日後在維護和發展上比較方便,由於BCB是使用由Object Pascal撰寫的VCL框架,因此當這兩個產品使用相同的後端編譯器之後,可讓BCB和Delphi的相容性更高。而且現在BCB在C/C++程式語言方面開始率先支援CPP0X標準,而Delphi又開始進入增加新的程式語言功能的階段,這個新的後端編譯器可以讓BCB和Delphi同時在程式語言方面大幅增加新的功能,因此非常讓人期待,更重要的是CodeGear可以在這個新的後端編譯器中加入更多最佳化的功能,在編譯器最佳化方面從Borland後期開始就很久沒有著墨了,因此我個人非常期待這個機會。

更有趣的是,在CodeGear中已經有許多人提倡混合編譯和跨平台編譯許多年了,但Borland/DevCo/CodeGear一直都沒有朝混合編譯和跨平台編譯發展,直到現在這個機會。在說明什麼是混合編譯和跨平台編譯之前,讓我們看看現在的BCB和Delphi這兩個產品如何編譯Delphi和C/C++原始程式。

在BCB和Delphi的BIN目錄下,BCC32和DCC32分別是BCB和Delphi的前端編譯器(Front End Compiler),目前BCB和Delphi分別是使用各自的後端編譯器,它們是comp32x.dll和dcc120.dll(我是使用RAD Studio 2009),如果我使用TDump來檢查這兩個dll輸出的函式,我們可以得到如下的結果:

2009開年動動腦!
在2009的大年初一終於去了花蓮一遊,應該有2, 3年沒有到花蓮了吧,當我走在海岸路之際乾涸許久的心靈仿佛立刻久旱逢甘霖,滋潤了起來,連腦筋似乎都活絡了起來。隔天騎著自行車沿著海岸路一路南行的路程中,封塵已久的思緒也逐漸的脫繭而出,回想這1,2年的變化可真大啊,不但在我個人的小世界中工作劇烈的改變中,世界的經濟狀況的變化更是令人瞠目結舌,對於5年級世代的人來說,在40多歲遇上這些巨大的衝擊應該是相當大的打擊吧。
回想這幾年來,從Borland,到DevCo,CodeGear最後到Embarcadero,我個人認為C++Builder,Delphi和JBuilder的未來似乎已經漸入佳境,為什麼? 因為:
第1,    2008年底Borland傳來非常不好的訊息,整個公司巨幅虧損不說,CEO等高階主管相繼離職,看來Borland出售開發工具之後不但沒有轉運,反而愈來愈糟糕,更證實了數年前 Borland決定放棄開發工具走向ALM是嚴重的錯誤,C++Builder,Delphi和JBuilder能夠離開Borland是最好的結果。
第2,    在2009年年初Embarcadero邀請我去舊金山參加全球大會,在Embarcadero的全球大會上我終於聽到了類似早年Borland全球大會的良好慣例,Embarcadero的CEO除了在銷售方面的強調之外,更強調了產品和品質的重要性,整個Embarcadero的全球大會也提供了許多產品和技術方面的訓練,而不像後期的Borland全球大會,Borland CEO只有滿嘴的空談和股票經,根本沒有公司和產品的發展計劃,整個Borland全球大會只有銷售訓練,產品和技術的內容一點都沒有。因此我在Embarcadero的全球大會上看到了C++Builder,Delphi和JBuilder在Embarcadero將有完全不一樣的未來。
第3,    全世界經濟狀況的改變讓許多人瞭解到簡單,好用的東西是最好的,因此許多人從昂貴的Java/.NET世界回到了原生Win32的開發世界中,準備迎接足夠未來數年使用的原生Win64開發平台的到來,這給了C++Builder,Delphi一個絕好的機會,因為原生Win64開發正是C++Builder,Delphi未來的發展道路。
第4,    這正是我想深入一點討論的內容,從許多跡象分析中可以發覺C++Builder,Delphi和JBuilder正在進行巨大的發展中,這些變化將帶來重大的改變,也將會激勵Win32和Win64開發工具的市場,對於C++Builder,Delphi和JBuilder的開發人員來說也將會覺得振奮不已。那麼C++Builder,Delphi和JBuilder會什麼樣的巨大改變呢? 讓我們一一的從一些蛛絲馬跡中分析一下,順便做為2009開年的腦筋體操,其實這些分析正是當我在花蓮海岸路一邊騎自行車一邊思考的結果。
首先我們知道從2年前開始DevCo和CodeGear便一直有公佈C++Builder,Delphi和JBuilder的發展路線圖,雖然後來DevCo和CodeGear的命運坎坷,以致C++Builder,Delphi和JBuilder的發展路線圖不斷的延後和改變,但在C++Builder,Delphi和JBuilder最終進入Embarcadero之後C++Builder,Delphi和JBuilder的發展路線也終於開始穩定下來。在前一陣子Delphi的產品經理Nick Hodges寫了一篇有關未來Delphi編譯器的文章:
http://dn.codegear.com/article/39174
在這篇文章中Nick說明了Delphi編譯器的歷史以及Delphi編譯器即將發展的方向,在其中Nick說Delphi64位元的編譯器將在2010年中才大概會準備好,因此合理的判斷Delphi 64最早應該會在2010底或是2011年初才可能出現,那麼在2009年C++Builder和Delphi會做什麼呢? 這也得從為什麼原生Delphi 64會從2009年底延遲到2010或2011年分析起。
在Nick的文章中說明了,CodeGear因為決定為C++Builder和Delphi開發一個共同的後端編譯器(Compiler Back End),因此延遲了原生BCB 64和Delphi 64,所謂共同的後端編譯器是指BCB 64和Delphi 64將使用一個共用的最佳化和機械程式碼產生器,如此一來不但日後在維護和發展上比較方便,由於BCB是使用由Object Pascal撰寫的VCL框架,因此當這兩個產品使用相同的後端編譯器之後,可讓BCB和Delphi的相容性更高。而且現在BCB在C/C++程式語言方面開始率先支援CPP0X標準,而Delphi又開始進入增加新的程式語言功能的階段,這個新的後端編譯器可以讓BCB和Delphi同時在程式語言方面大幅增加新的功能,因此非常讓人期待,更重要的是CodeGear可以在這個新的後端編譯器中加入更多最佳化的功能,在編譯器最佳化方面從Borland後期開始就很久沒有著墨了,因此我個人非常期待這個機會。
更有趣的是,在CodeGear中已經有許多人提倡混合編譯和跨平台編譯許多年了,但Borland/DevCo/CodeGear一直都沒有朝混合編譯和跨平台編譯發展,直到現在這個機會。在說明什麼是混合編譯和跨平台編譯之前,讓我們看看現在的BCB和Delphi這兩個產品如何編譯Delphi和C/C++原始程式。
在BCB和Delphi的BIN目錄下,BCC32和DCC32分別是BCB和Delphi的前端編譯器(Front End Compiler),目前BCB和Delphi分別是使用各自的後端編譯器,它們是comp32x.dll和dcc120.dll(我是使用RAD Studio 2009),如果我使用TDump來檢查這兩個dll輸出的函式,我們可以得到如下的結果:

Exports from comp32x.dll
  44 exported name(s), 44 export addresse(s).  Ordinal base is 1.
  Sorted by Name:
    RVA      Ord. Hint Name
    ——– —- —- —-
    0016E65C   32 0000 ASMFILENAME
    0016E664   34 0001 ASMOPTIONS
    0010C008   44 0002 BCCGETINTERFACE
    00005A44   25 0003 BREAKCOMPILE
    000FFAB8   14 0004 BROWSERFILEINDEXTONAME
    000FCE90    1 0005 BROWSERFINDDECLARATION
    000FE48C    6 0006 BROWSERFINDSYMBOL
    000FD1D0    4 0007 BROWSERGETAUTORESULTTYPE
    000FD1C4    3 0008 BROWSERGETAUTOTYPE
    000FF9DC   13 0009 BROWSERGETBASETYPE
    000FE4B8    7 000A BROWSERGETOBJTYPE
    000FD0D0    2 000B BROWSERGETREFERENCES
    000FF82C   11 000C BROWSERGETRESULTTYPE
    000FE5F8    8 000D BROWSERGETSYMBOLFLAGS
    000FDCE0    5 000E BROWSERGETSYMBOLS
    000FF070    9 000F BROWSERGETSYMBOLTEXT
    000FF0EC   10 0010 BROWSERGETTYPECODE
    000FF940   12 0011 BROWSERGETTYPESYMBOL
    000054F4   28 0012 COMPILE
    00005528   29 0013 COMPILEANDBROWSE
    00005568   30 0014 COMPILEANDKIBITZ
    000055E0   31 0015 COMPILEWITHOPTIONS
    0014110C   36 0016 COMPMESSAGES
    0014A0F3   24 0017 CONFIG
    0016E7C0   27 0018 CUMLINENO
    0010CCEC   22 0019 DbEval32InitProc
    00141BC4   40 001A ERRBREAK
    001CAD28   26 001B FILENAME
    00141BC0   37 001C FIRSTERROR
    00141BB8   38 001D FIRSTWARNING
    00004B2C   42 001E FLUSHPCH
    0011C0AC   43 001F GetCompilerListeners
    00100888   16 0020 KIBITZGETARGINDEX
    0010087C   15 0021 KIBITZGETKIND
    00100D20   21 0022 KIBITZGETOVERLOADS
    00100CEC   20 0023 KIBITZGETVALIDSYMBOLS
    00100898   17 0024 KIBITZRESULTGETFLAGS
    001008D0   19 0025 KIBITZRESULTGETNAME
    001008B0   18 0026 KIBITZRESULTSETFLAGS
    0016E660   33 0027 OBJFILENAME
    00005614   41 0028 TOTALERRORCOUNT
    00141BBC   39 0029 WARNINGCOUNT
    00149C70   35 002A WARNINGS
    0013E0F8   23 002B ___CPPdebugHook

Exports from dcc120.dll
  105 exported name(s), 112 export addresse(s).  Ordinal base is 8.
  Sorted by Name:
    RVA      Ord. Hint Name
    ——– —- —- —-
    0000ECA0   73 0000 BrowserFindDeclaration
    0000F54C   84 0001 BrowserFindSymNamespace
    0000CC24   58 0002 BrowserFindSymSource
    0000F4FC   83 0003 BrowserFindSymUnit
    0000CBA0   57 0004 BrowserFindSymbol
    0000F4C8   82 0005 BrowserFindUnit
    0000F660   89 0006 BrowserGetAncestor
    0000F738   93 0007 BrowserGetArrayIndex
    0000F6FC   92 0008 BrowserGetArrayIndexSymFromType
    0000F7CC   96 0009 BrowserGetArrayOfSym
    0000F7A8   95 000A BrowserGetArrayOfSymFromType
    0000F7E8   97 000B BrowserGetArrayOfType
    0000F754   94 000C BrowserGetArrayOfTypeFromType
    0000F974  102 000D BrowserGetAssemblyLocation
    0000F27C   78 000E BrowserGetAutoResultType
    0000F21C   77 000F BrowserGetAutoType
    0000EC64   72 0010 BrowserGetBaseType
    0000E468   64 0011 BrowserGetCallingConvention
    0000F620   88 0012 BrowserGetClassHelpers
    0000F5A4   85 0013 BrowserGetClassRef
    0000FAB0  104 0014 BrowserGetContainsList
    0000F804   98 0015 BrowserGetDefaultProperty
    0000E3C8   63 0016 BrowserGetDefaultValue
    0000F2E0   79 0017 BrowserGetDirectlyUsedUnits
    0000F6D8   91 0018 BrowserGetHelpedType
    0000F6A0   90 0019 BrowserGetImplementedInterfaces
    0000F5F0   87 001A BrowserGetInheritedScope
    0000F0D0   75 001B BrowserGetObjType
    0000D900   61 001C BrowserGetOverloads
    0000F948  101 001D BrowserGetPointedType
    0000F010   74 001E BrowserGetReferences
    0000EB84   69 001F BrowserGetResultType
    0000EBCC   70 0020 BrowserGetResultTypeType
    0000F4B0   81 0021 BrowserGetSymbolDocumentation
    0000DB5C   62 0022 BrowserGetSymbolFlags
    0000FA88  103 0023 BrowserGetSymbolNameOffset
    0000F3F4   80 0024 BrowserGetSymbolPath
    0000E480   65 0025 BrowserGetSymbolText
    0000E4B0   66 0026 BrowserGetSymbolTextBuff
    0000F5CC   86 0027 BrowserGetSymbolValue
    0000D7D0   60 0028 BrowserGetSymbols
    0000F888  100 0029 BrowserGetSymbolsFromUnit
    0000EB58   68 002A BrowserGetTypeCode
    0000E9C8   67 002B BrowserGetTypeCodeType
    0000F200   76 002C BrowserGetTypeFromSymbol
    0000EC10   71 002D BrowserGetTypeSymbol
    0000F874   99 002E BrowserGetUnitSymbol
    0008852C  108 002F BuildPackages
    0007A994  107 0030 CallNextUnitFreeHook
    0000B4BC   52 0031 ClearAllStates
    0000B4CC   53 0032 ClearCompState
    00002868   20 0033 ClearPackageCache
    00002854   19 0034 ClearUnitCache
    000021BC   13 0035 CompilerCompile
    000021E0   14 0036 CompilerCompileCmdLine
    0000219C   12 0037 CompilerCompileUnit
    00001FA8   11 0038 CompilerDone
    00002738   18 0039 CompilerFindError
    0000237C   15 003A CompilerGetUnit
    000024B0   16 003B CompilerGetUnitSymbol
    00001F2C   10 003C CompilerInit
    00002B2C   26 003D CompilerShouldCompile
    00002B70   27 003E CompilerVerifyCodePageOption
    0001673C    8 003F DbEval32InitProc
    00001754    9 0040 DccInitialize
    000084F8   43 0041 DoneEvaluate
    000084C0   41 0042 DoneProcess
    00006D2C   30 0043 EvalCondition
    000068A8   28 0044 Evaluate
    00007C64   34 0045 FindLineCode
    00007D1C   35 0046 FindLineCodes
    00007DF0   36 0047 FindSourceLine
    000088A8   44 0048 FreeCompile
    00007428   31 0049 GetCallCount
    000079CC   33 004A GetCallHeader
    00007438   32 004B GetCallPos
    000083C4   39 004C GetCodePosRanges
    00008154   38 004D GetCodeRanges
    0000A60C   48 004E GetFileCount
    0000A8AC   51 004F GetFileIndex
    0000A61C   49 0050 GetFileName
    0000A27C   47 0051 GetNearestSymName
    00008968   46 0052 GetPropertyInfo
    000080AC   37 0053 GetSrcLines
    000084E4   42 0054 InitEvaluate
    00008474   40 0055 InitProcess
    0000250C   17 0056 KibitzCompiler
    000A19B0  112 0057 KibitzGetOverloads
    0008C068  109 0058 KibitzGetValidSymbols
    00090F5C  111 0059 LoadCompState
    000088BC   45 005A LookupProc
    0000CDF8   59 005B MakeSureUnitIsLinked
    00006CFC   29 005C Modify
    0000B588   54 005D NewCompState
    000908F0  110 005E SaveCompState
    0000B604   56 005F SetCompState
    0000B5E4   55 0060 SetCompStateFast
    0000A64C   50 0061 SetFileName
    0007A974  106 0062 SetUnitFreeHook
    00002974   23 0063 UIDiscardUnit
    00002924   22 0064 UIGetExplicitUnitImports
    000029A0   24 0065 UIGetPackagesUsed
    00002878   21 0066 UILoadUnit
    00002A08   25 0067 UISetDebugDir
    001150FC  105 0068 ___CPPdebugHook

各位看到上面許多的輸出函式都和編譯工作有關的嗎? 從上面的結果我們可以使用下列簡化的圖形來呈現:


等到新的後端編譯器出來之後,BCB和Delphi的編譯架構會形成如下的狀態:
 

OK,那麼混合編譯和跨平台編譯是什麼? 動腦想想如果我們再把機械碼產生器抽離出來形成如下的架構:

你看到了什麼?
現在回到BCB和Delphi本身,現在BCB/Delphi中的dbExpress是跨平台的架構,RTL在擁有了跨平台編譯之後也就可以跨平台了,
If
begin
  Delphi程式語言 + VCL + RTL + dbExpress ~= Delphi 而且
  C/C++程式語言 +  VCL + RTL + dbExpress ~= BCB 的話,
end
then
begin
  Delphi程式語言 + RTL + dbExpress + 跨平台編譯 = ?
  C/C++程式語言 +  RTL + dbExpress +跨平台編譯 = ?
end

剩下的問題就是VCL了,VCL在原生Win32/Win64不是問題,但在Linux或是其他平台怎麼辦? 還記得CLX嗎? 本來Borland說要開放CLX,但現在CodeGear又似乎踩剎車了,為什麼? 我也不知道, 但我想如果我們把CLX帶入上面的公式:

Delphi程式語言 + 新的CLX + RTL + dbExpress + 跨平台編譯 = ?
C/C++程式語言 +  新的CLX + RTL + dbExpress +跨平台編譯 = ?

真是令人好奇啊,希望我猜的都能成真,那麼C++Builder和Delphi將進化成最佳的”跨平台原生開發工具”, 也別忘記現在由Delphi Prism建立的應用程式已經可以執行在Window, Linux和Mac等 3個平台之上了。

我知道現在BCB 2009/Delphi 2009的Patch 3和Patch 4都在開發之中,從目前的測試版來看CodeGear修正了許多多年的臭蟲,整個速度和穩定性更勝RAD Studio 2009,所以我猜想2009年CodeGear會再推出一個BCB/Delphi 2010的32位元版本,這個版本將會是最穩定,最快速的32位元版本,而且應該會支援Vista和Window 7等和其他許多最新的PC技術,CodeGear在離開Borland之後決心再把C++Builder/Delphi打造成最好的Win32/Win64開發工具看來是非常認真的。

好了,大過年的寫到這裡文章也夠長的了,我也該去打打Wii和Wii Fit了,下次再讓我們繼續的動動腦吧(後註, 這篇文章我在大年初四就寫完了, 只是忘了Post出來, 看來記性愈來愈差了)。

最後祝各位 新年快樂,2009年心想事成

11 則迴響

興德開始提供CodeGear技術文章

如果您還不知道的話,興德資訊開始在興德的網站上提供我寫的一些技術文章的和書提供有需要的朋友下載使用,這個小小的園地希望能夠提供一些中文的CodeGear技術資料給有需要的朋友。

我們希望一開始至少在這個小小的技術網提供技術文章,我以前舊的書籍和技術研討會相關的slides和範例程式,我們更我們希望日後擁有更多的資源可以提供更多的東西,而且能夠繼續的維護下去,當然我們更需要您的支持,謝謝!

這個技術網目前的URL是 :


http://www.sinter.com.tw/codegear/codegear_technique.html

4 則迴響