这里有篇资料,你参考一下<br>虽然Delphi作为一种极其优秀的开发工具已经被越来越多的开发人员选用,但是它毕竟面世时间不算太长,加上有的软件开发厂商实力不强或是其他原因,造成部分二次开发平台仅仅提供C语言的开发接口。<br>但这并不是说用Delphi就不能完成这些工作.我们知道,软件厂商提供开发包实际基本上都是以动态连接库的方式实现的,他们将可以调用的函数、过程包括一些特定数据格式组合起来, 作为一个开发包,通过c编译器形成一个可重用的DLL文件,而所谓的开发接口往往就是动态连接库(.dll)的声明文件,他们即使提供Delphi下的接口,也就是用Pascal写一遍对这些动态库的声明。如果我们自己作这个翻译工作,就不存在厂商是否提供Delphi下接口的问题了。换言之,对于以DLL方式出现的开发包,只要有c的文件头,理论上都可以在Delphi下照样开发。<br>经过对比,我们发现c语言中存在的所有数据类型在Delphi的Object Pascal中都有对应类型存在;同时c语言调用动态库的4种方式在Delphi编译器中也都覆盖了,这就保证了我们的工作是可行的,如果你对此尚有疑问,那么可以看看WinProcs和ShellAPI两个单元。这两个单元就是Inprise写的对Windows系统函数(也是C语言开发,存在于DLL文件中的)的声明调用。<br>这里我们就来看看写这个声明文件需要注意的一些问题。在delphi中有两种声明方式:implicit (静态的) 和 explicit (动态的)。<br>对于implicit方式要求程序运行时动态库一定要存在,否则程序不能运行.而explicit方式可以没有动态库存在.例如一个界面程序,如果3维显示是在一个dll中实现的,那么我们如果采用explicit方式调用就可以做到如果动态库存在就用3维显示,否则用2维显示。<br>采用explicit方式的另一个好处是可以加快程序的启动速度.因为explicit方式让程序在执行到调用语句时才装载dll文件.但同时implicit方式比较简单,所以用的也更多。<br> implicit方式的典型声明格式是:<br> procedure Foo(X: Integer); external 'BAR' index 1;<br> 这里再次提醒:如果程序找不到对应的dll文件,在编译和运行时都会出现错误。<br> Explicit方式就麻烦一些了.实际上这种方式在vb中用的更多一些.如果你的确希望这样做,那么可以参考下面的代码:<br> var Hbar: Thandle;<br> Foo: procedure (X: Integer); {$IFDEF WIN32} stdcall; {$ENDIF} <br> begin<br> Hbar := LoadLibrary('BAR.DLL');<br> if Hbar 〉= 32 then { success } begin<br> Foo := GetProcAddress(HBar, 'FOO');<br> ... <br> Foo(1); <br><br> ...<br> FreeLibrary(HBar); <br> end<br> else MessageDlg('警告: 没有发现 BAR.DLL', mtError, [mbOk], 0) <br> end.<br>请注意一下, 这段代码编译时是不会出现错误的,在运行时也会按照程序指定步骤完成.DLL的调入时间也如我们前面提及的,是在需要时才引入的。<br>在c语言中常常采用IMPLIB和IMPDEF两个工具生成.h文件,这个文件就是开发包中我们见到的头文件了.我们需要作的工作就是将这个文件准确地翻译成pascal格式,而且可以被编译器准确的用来编译成dll的声明文件。<br>为了更好的说明问题,我们不妨先看看一个简化的c语言的头文件: <br> /**********/ *<br> * wing.h - WinG functions, types, and definitions *<br> * Copyright (c) 1994 Microsoft Corp. All rights reserved. *<br> /*********/ <br> #ifndef _INC_WING<br> #define _INC_WING <br> #ifndef _INC_WINDOWS<br> #include /* Include windows.h if not already included */ <br> #endif<br> #ifdef __cplusplus<br> extern "C" { /* Assume C declarations for C++ */<br> #endif <br> #if defined(WIN32) || defined(_WIN32) <br> #define WINGAPI WINAPI #else<br> #define WINGAPI WINAPI _loadds <br> #endif<br> /***** WingDC and WinGBitmap ********/<br> HDC WINGAPI WinGCreateDC( void );<br> BOOL WINGAPI WinGRecommendDIBFormat( BITMAPINFO FAR *pFormat );<br> HBITMAP WINGAPI WinGCreateBitmap( HDC WinGDC, BITMAPINFO const FAR *pHeader,void FAR *FAR *ppBits )<br> void FAR *WINGAPI WinGGetDIBPointer( HBITMAP WinGBitmap,BITMAPINFO FAR *pHeader );<br> UINT WINGAPI WinGGetDIBColorTable( HDC WinGDC, UINT StartIndex,UINT NumberOfEntries, RGBQUAD FAR *pColors );<br> UINT WINGAPI WinGSetDIBColorTable( HDC WinGDC, UINT StartIndex,<br> UINT NumberOfEntries, RGBQUAD const FAR *pColors );<br> /***** Halftoning **********/<br> HPALETTE WINGAPI WinGCreateHalftonePalette( void );<br> typedef enum WING_DITHER_TYPE<br> { WING_DISPERSED_4x4,WING_DISPERSED_8x8,WING_CLUSTERED_4x4} WING_DITHER_TYPE;<br> HBRUSH WINGAPI WinGCreateHalftoneBrush( HDC Context, COLORREF crColor,WING_DITHER_TYPE DitherType );<br> /***** Blts **********/<br> BOOL WINGAPI WinGBitBlt( HDC hdcDest, int nXOriginDest,int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,int nXOriginSrc, int nYOriginSrc );<br> BOOL WINGAPI WinGStretchBlt( HDC hdcDest, int nXOriginDest,int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc );<br> #ifdef __cplusplus <br> } /* End of extern "C" */ <br> #endif<br> #endif // _INC_WING<br>从中我们可以归纳出需要翻译的三部分内容:编译开关,数据结构,函数调用。为了便于大家完成翻译工作,我摘抄了一张c语言和pascal语言的数据类型对照表,可以供大家参考:<br><br>C/C++ Type<br> Object Pascal Type<br> C/C++ Type<br> Object Pascal Type<br> <br>unsigned short [int]<br> word <br> char <br> char <br> <br>[signed] short [int] <br> smallint <br> signed char <br> shortint <br> <br>unsigned [int] <br> cardinal { 3.25 fix } <br> unsigned char <br> byte <br> <br>[signed] int <br> integer <br> char* <br> pchar <br> <br>uint <br> longint { or cardinal } <br> lpstr or pstr <br> pchar <br> <br>word <br> word <br> lpwstr or pwstr <br> pwidechar { 3.12 fix } <br> <br>dword <br> longint { or cardinal } <br> void* <br> pointer <br> <br>unsigned long <br> longint { or cardinal } <br> bool <br> bool <br> <br>unsigned long int <br> longint { or cardinal } <br> float <br> single <br> <br>[signed] long <br> longint <br> double <br> double <br> <br>[signed] long int <br> longint <br> <br><br> 下面是一些常用和常见数据结构的对照表: <br><br><br>C/C++ Type<br> Object Pascal Type<br> C/C++ Type<br> Object Pascal Type<br> <br>handle<br> thandle <br> debughookinfo <br> tdebughookinfo <br> <br>farproc <br> tfarproc <br> bitmapcoreheader <br> tbitmapcoreheader <br> <br>atom <br> tatom <br> bitmapinfoheader <br> tbitmapinfoheader <br> <br>tpoint <br> tpoint <br> bitmapinfo <br> tbitmapinfo <br> <br>trect <br> trect <br> bitmapcoreinfo <br> tbitmapcoreinfo <br> <br>colorref <br> tcolorref <br> bitmapfileheader <br> tbitmapfileheader <br> <br>ofstruct <br> tofstruct <br> ttpolygonheader <br> tpolygonheader <br> <br>handletable <br> thandletable <br> rasterizer_status <br> trasterizer_status <br> <br>bitmap <br> tbitmap <br> mousehookstruct <br> tmousehookstruct <br> <br>rgbtriple <br> trgbtriple <br> cbtactivatestruct <br> tcbtactivatestruct <br> <br>rgbquad <br> trgbquad <br> hardwarehookstruct <br> thardwarehookstruct <br> <br>metarecord <br> tmetarecord <br> eventmsg <br> teventmsg <br> <br>metaheader <br> tmetaheader <br> pattern <br> tpattern { tlogbrush } <br> <br>metafilepict <br> tmetafilepict <br> newtextmetric <br> tnewtextmetric <br> <br>textmetric <br> ttextmetric <br> paletteentry <br> tpaletteentry <br> <br>logbrush <br> tlogbrush <br> logpalette <br> tlogpalette <br> <br>logpen <br> tlogpen <br> kerningpair <br> tkerningpair <br> <br>logfont <br> tlogfont <br> outlinetextmetric <br> toutlinetextmetric <br> <br>enumlogfont <br> tenumlogfont <br> glyphmetrics <br> tglyphmetrics <br> <br>panose <br> tpanose <br> pointfx <br> tpointfx <br> <br>fixed <br> tfixed <br> ttpolycurve <br> tttpolycurve <br> <br>mat2 <br> tmat2 <br> minmaxinfo <br> tminmaxinfo <br> <br>abc <br> tabc <br> paintstruct <br> tpaintstruct <br> <br>wndclass <br> twndclass <br> createstruct <br> tcreatestruct <br> <br>msg <br> tmsg <br> cbt_createwnd <br> tcbt_createwnd <br> <br>seginfo <br> tseginfo <br> measureitemstruct <br> tmeasureitemstruct <br> <br>accel <br> taccel <br> drawitemstruct <br> tdrawitemstruct <br> <br>size <br> tsize <br> deleteitemstruct <br> tdeleteitemstruct <br> <br>dcb <br> tdcb <br> compareitemstruct <br> tcompareitemstruct <br> <br>comstat <br> tcomstat <br> windowpos <br> twindowpos <br> <br>helpwininfo <br> thelpwininfo <br> windowplacement <br> twindowplacement <br> <br>ctlstyle <br> tctlstyle <br> nccalcsize_params <br> tnccalcsize_params <br> <br>ctltype <br> tctltype <br> menuitemtemplateheader <br> tmenuitemtemplateheader <br> <br>ctlinfo <br> tctlinfo <br> menuitemtemplate <br> tmenuitemtemplate <br> <br>ddeadvise <br> tddeadvise <br> mdicreatestruct <br> tmdicreatestruct <br> <br>ddedata <br> tddedata <br> clientcreatestruct <br> tclientcreatestruct <br> <br>ddepoke <br> tddepoke <br> multikeyhelp <br> tmultikeyhelp <br> <br>ddeaack <br> tddeack <br> kanjistruct <br> tkanjistruct <br> <br>devmode <br> tdevmode <br> <br><br>以上仅仅是常用的一部分,更多的结构转换可以参见WINDOWS.H头文件和WINDOWS.pas,将两者作一个对比可以学习到许多技巧。<br>在上面的c语言文件头中您应该可以按照上表作出转换了。可能存在的问题是一个数据结构的变换:<br> typedef enum WING_DITHER_TYPE<br> {WING_DISPERSED_4x4,WING_DISPERSED_8x8,WING_CLUSTERED_4x4} WING_DITHER_TYPE;<br> 这是一个枚举结构,我们可以翻译成这样:<br> Type WING_DITHER_TYPE =(WING_DISPERSED_4x4,WING_DISPERSED_8x8,WING_CLUSTERED_4x4);<br><br> 我们再来看看函数和过程的转换吧:<br> WinGCreateDC function: <br> HDC WINGAPI WinGCreateDC( void );<br> 显然这是一个没有返回值的函数,而且没有入口参数,我们可以将其转换成:<br> function WinGCreateDC: HDC; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1001;<br>这里的index 1001是从IMPDEF的.DEF 文件中得到的,一些反编译和调试工具也可以得到其值.但是我们推荐采用按照名称方式访问,这样可以适合于更多的场合。<br> 按照同样的方式,我们再来翻译几个函数:<br> function WinGRecommendDIBFormat(pFormat: PBitmapInfo): Bool; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1002; <br> function WinGCreateBitmap(WinGDC: HDC;Const pHeader: PBitmapInfo;ppBits: PPointer): HBITMAP; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1003;<br> function WinGCreateHalftoneBrush(Context: HDC;crColor: TColorRef;DitherType: WING_DITHER_TYPE): HBRUSH; {$IFDEF WIN32} stdcall; {$ENDIF} external 'WING' index 1008; <br>这些都是按照静态方式声明的。<br>编译器指令的翻译是相对比较麻烦的事情.而且要考虑到32位代码和16位代码的兼容性.一般我们采用{$IFDEF WIN32}{$ENDIF}这种方式处理这个问题.<br>最后我们推荐一个很好的代码自动转换辅助工具headConv.这是著名的荷兰程序员Bob的杰作.最初的版本(1.0,2.0)是要收费的(25美金),我们得到了其最新的一个免费版本3.25命令行版,你可以从一个delphi控件收集站点(delphi根据地 http://warez.zb169.net/)去下载它.其用法也非常简单,一共有三个可选项:<br> -o 覆盖原有单元<br> -x 强制产生动态声明单元;<br> -m 强制产生静态声明单元;<br>这样就可以大大减少手工翻译的时间,而将主要精力用于润色和优化。