轉換c++ source to pascal |
尚未結案
|
jjyeah
一般會員 發表:10 回覆:11 積分:4 註冊:2002-06-27 發送簡訊給我 |
|
flyup
資深會員 發表:280 回覆:508 積分:385 註冊:2002-04-15 發送簡訊給我 |
C-to-Pascal Header Converter (含原始碼)
ftp://delphi-jedi.org//darth/headconv.zip
|
flyup
資深會員 發表:280 回覆:508 積分:385 註冊:2002-04-15 發送簡訊給我 |
雖然Delphi作為一種極其優秀的開發工具已經被越來越多的開發人員選用,但是它畢竟面世時間不算太長,加上有的軟體開發廠商實力不強或是其他原因,造成部分二次開發平台僅僅提供C語言的開發介面。 但這並不是說用Delphi就不能完成這些工作.我們知道,軟體廠商提供開發包實際基本上都是以動態連接庫的方式實現的,他們將可以調用的函數、過程包括一些特定資料格式組合起來, 作為一個開發包,通過c編譯器形成一個可重用的DLL文件,而所謂的開發介面往往就是動態連接庫(.dll)的宣告文件,他們即使提供Delphi下的介面,也就是用Pascal寫一遍對這些動態庫的宣告。如果我們自己作這個翻譯工作,就不存在廠商是否提供Delphi下介面的問題了。換言之,對於以DLL方式出現的開發包,只要有c的文件頭,理論上都可以在Delphi下照樣開發。 經過對比,我們發現c語言中存在的所有資料類型在Delphi的Object Pascal中都有對應類型存在;同時c語言調用動態庫的4種方式在Delphi編譯器中也都覆蓋了,這就保證了我們的工作是可行的,如果你對此尚有疑問,那麼可以看看WinProcs和ShellAPI兩個單元。這兩個單元就是Inprise寫的對Windows系統函數(也是C語言開發,存在於DLL文件中的)的宣告調用。 這裡我們就來看看寫這個宣告文件需要注意的一些問題。在delphi中有兩種宣告方式:implicit (靜態的) 和 explicit (動態的)。 對於implicit方式要求程序執行時動態庫一定要存在,否則程序不能執行.而explicit方式可以沒有動態庫存在.例如一個界面程序,如果3維顯示是在一個dll中實現的,那麼我們如果採用explicit方式調用就可以做到如果動態庫存在就用3維顯示,否則用2維顯示。 採用explicit方式的另一個好處是可以加快程序的啟動速度.因為explicit方式讓程序在執行到調用語句時才裝載dll文件.但同時implicit方式比較簡單,所以用的也更多。 implicit方式的典型宣告格式是: procedure Foo(X: Integer); external 'BAR' index 1; 這裡再次提醒:如果程序找不到對應的dll文件,在編譯和執行時都會出現錯誤。 Explicit方式就麻煩一些了.實際上這種方式在vb中用的更多一些.如果你的確希望這樣做,那麼可以參考下面的程式碼: var Hbar: Thandle; Foo: procedure (X: Integer); {$IFDEF WIN32} stdcall; {$ENDIF} begin Hbar := LoadLibrary('BAR.DLL'); if Hbar 〉= 32 then { success } begin Foo := GetProcAddress(HBar, 'FOO'); ... Foo(1); ... FreeLibrary(HBar); end else MessageDlg('警告: 沒有發現 BAR.DLL', mtError, [mbOk], 0) end. 請注意一下, 這段程式碼編譯時是不會出現錯誤的,在執行時也會按照程序指定步驟完成.DLL的調入時間也如我們前面提及的,是在需要時才引入的。 在c語言中常常採用IMPLIB和IMPDEF兩個工具生成.h文件,這個文件就是開發包中我們見到的頭文件了.我們需要作的工作就是將這個文件準確地翻譯成pascal格式,而且可以被編譯器準確的用來編譯成dll的宣告文件。 為了更好的說明問題,我們不妨先看看一個簡化的c語言的頭文件: /**********\ * * wing.h - WinG functions, types, and definitions * * Copyright (c) 1994 Microsoft Corp. All rights reserved. * \*********/ #ifndef _INC_WING #define _INC_WING #ifndef _INC_WINDOWS #include /* Include windows.h if not already included */ #endif #ifdef __cplusplus extern "C" { /* Assume C declarations for C++ */ #endif #if defined(WIN32) || defined(_WIN32) #define WINGAPI WINAPI #else #define WINGAPI WINAPI _loadds #endif /***** WingDC and WinGBitmap ********/ HDC WINGAPI WinGCreateDC( void ); BOOL WINGAPI WinGRecommendDIBFormat( BITMAPINFO FAR *pFormat ); HBITMAP WINGAPI WinGCreateBitmap( HDC WinGDC, BITMAPINFO const FAR *pHeader, void FAR *FAR *ppBits ) void FAR *WINGAPI WinGGetDIBPointer( HBITMAP WinGBitmap, BITMAPINFO FAR *pHeader ); UINT WINGAPI WinGGetDIBColorTable( HDC WinGDC, UINT StartIndex, UINT NumberOfEntries, RGBQUAD FAR *pColors ); UINT WINGAPI WinGSetDIBColorTable( HDC WinGDC, UINT StartIndex, UINT NumberOfEntries, RGBQUAD const FAR *pColors ); /***** Halftoning **********/ HPALETTE WINGAPI WinGCreateHalftonePalette( void ); typedef enum WING_DITHER_TYPE { WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4 } WING_DITHER_TYPE; HBRUSH WINGAPI WinGCreateHalftoneBrush( HDC Context, COLORREF crColor, WING_DITHER_TYPE DitherType ); /***** Blts **********/ BOOL WINGAPI WinGBitBlt( HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc ); BOOL WINGAPI WinGStretchBlt( HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc ); #ifdef __cplusplus } /* End of extern "C" */ #endif #endif // _INC_WING 從中我們可以歸納出需要翻譯的三部分內容:編譯開關,資料結構,函數調用。為了便於大家完成翻譯工作,我摘抄了一張c語言和pascal語言的資料類型對照表,可以供大家參考: C/C++ Type`ObjectPascal Type unsigned short [int] word
[signed] short [int] smallint
unsigned [int] cardinal { 3.25 fix }
[signed] int integer
uint longint { or cardinal }
word word
dword longint { or cardinal }
unsigned long longint { or cardinal }
unsigned long int longint { or cardinal }
[signed] long longint
[signed] long int longint
char char
signed char shortint
unsigned char byte
char* pchar
lpstr or pstr pchar
lpwstr or pwstr pwidechar { 3.12 fix }
void* pointer
bool bool
float single
double double 下面是一些常用和常見資料結構的對照表: handle thandle
farproc tfarproc
atom tatom
tpoint tpoint
trect trect
colorref tcolorref
ofstruct tofstruct
debughookinfo tdebughookinfo
bitmap tbitmap
rgbtriple trgbtriple
rgbquad trgbquad
bitmapcoreheader tbitmapcoreheader
bitmapinfoheader tbitmapinfoheader
bitmapinfo tbitmapinfo
bitmapcoreinfo tbitmapcoreinfo
bitmapfileheader tbitmapfileheader
handletable thandletable
metarecord tmetarecord
metaheader tmetaheader
metafilepict tmetafilepict
textmetric ttextmetric
newtextmetric tnewtextmetric
logbrush tlogbrush
logpen tlogpen
pattern tpattern { tlogbrush }
paletteentry tpaletteentry
logpalette tlogpalette
logfont tlogfont
enumlogfont tenumlogfont
panose tpanose
kerningpair tkerningpair
outlinetextmetric toutlinetextmetric
fixed tfixed
mat2 tmat2
glyphmetrics tglyphmetrics
pointfx tpointfx
ttpolycurve tttpolycurve
ttpolygonheader tpolygonheader
abc tabc
rasterizer_status trasterizer_status
mousehookstruct tmousehookstruct
cbtactivatestruct tcbtactivatestruct
hardwarehookstruct thardwarehookstruct
eventmsg teventmsg
wndclass twndclass
msg tmsg
minmaxinfo tminmaxinfo
seginfo tseginfo
accel taccel
paintstruct tpaintstruct
createstruct tcreatestruct
cbt_createwnd tcbt_createwnd
measureitemstruct tmeasureitemstruct
drawitemstruct tdrawitemstruct
deleteitemstruct tdeleteitemstruct
compareitemstruct tcompareitemstruct
windowpos twindowpos
windowplacement twindowplacement
nccalcsize_params tnccalcsize_params
size tsize
menuitemtemplateheader tmenuitemtemplateheader
menuitemtemplate tmenuitemtemplate
dcb tdcb
comstat tcomstat
mdicreatestruct tmdicreatestruct
clientcreatestruct tclientcreatestruct
multikeyhelp tmultikeyhelp
helpwininfo thelpwininfo
ctlstyle tctlstyle
ctltype tctltype
ctlinfo tctlinfo
ddeadvise tddeadvise
ddedata tddedata
ddepoke tddepoke
ddeaack tddeack
devmode tdevmode
kanjistruct tkanjistruct
... ... 以上僅僅是常用的一部分,更多的結構轉換可以參見WINDOWS.H頭文件和WINDOWS.pas,將兩者作一個對比可以學習到許多技巧。 在上面的c語言文件頭中您應該可以按照上表作出轉換了。可能存在的問題是一個資料結構的變換: typedef enum WING_DITHER_TYPE { WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4 } WING_DITHER_TYPE; 這是一個枚舉結構,我們可以翻譯成這樣: Type WING_DITHER_TYPE = (WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4); 我們再來看看函數和過程的轉換吧: WinGCreateDC function: HDC WINGAPI WinGCreateDC( void ); 顯然這是一個沒有返回值的函數,而且沒有入口參數,我們可以將其轉換成: function WinGCreateDC: HDC; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1001; 這裡的index 1001是從IMPDEF的.DEF 文件中得到的,一些反編譯和調試工具也可以得到其值.但是我們推薦採用按照名稱方式訪問,這樣可以適合於更多的場合。 按照同樣的方式,我們再來翻譯幾個函數: function WinGRecommendDIBFormat(pFormat: PBitmapInfo): Bool; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1002; function WinGCreateBitmap(WinGDC: HDC; Const pHeader: PBitmapInfo; ppBits: PPointer): HBITMAP; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1003; function WinGCreateHalftoneBrush(Context: HDC; crColor: TColorRef; DitherType: WING_DITHER_TYPE): HBRUSH; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1008; 這些都是按照靜態方式宣告的。 編譯器指令的翻譯是相對比較麻煩的事情.而且要考慮到32位程式碼和16位程式碼的兼容性.一般我們採用{$IFDEF WIN32} ; ...... {$ENDIF} 這種方式處理這個問題. 最後我們推薦一個很好的程式碼自動轉換輔助工具headConv.這是著名的荷蘭程序員Bob的傑作.最初的版本(1.0,2.0)是要收費的(25美金),我們得到了其最新的一個免費版本3.25命令行版,你可以從我的一個delphi元件收集站點(delphi根據地 ftp://delphi-jedi.org//darth/headconv.zip)去下載它.其用法也非常簡單,一共有三個可選項: -o 覆蓋原有單元 -x 強制產生動態宣告單元; -m 強制產生靜態宣告單元; 這樣就可以大大減少手工翻譯的時間,而將主要精力用於潤色和優化。
|
johnny.guo
一般會員 發表:0 回覆:4 積分:0 註冊:2002-12-20 發送簡訊給我 |
|
flyup
資深會員 發表:280 回覆:508 積分:385 註冊:2002-04-15 發送簡訊給我 |
|
flyup
資深會員 發表:280 回覆:508 積分:385 註冊:2002-04-15 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |