这个你看一下吧<br>标题:从C到Delphi的接口声明转换 (2分) <br>Oldtiger (2001-11-1 17:26) 700803 <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>从中我们可以归纳出需要翻译的三部分内容:编译开关,数据结构,函数调用。为了便于大家完成翻译工作,我摘抄了一张<br><br>c语言和pascal语言的数据类型对照表,可以供大家参考:<br><br>C/C++ Type Object Pascal <br> <br>char char <br>signed char shortint <br>unsigned char byte <br>unsigned short [int] word <br>[signed] short [int] smallint <br>unsigned [int] cardinal { 3.25 fix } <br>[signed] int integer <br>char* pchar <br>uint longint { or cardinal } <br>lpstr or pstr pchar <br>word word <br>lpwstr or pwstr pwidechar { 3.12 fix } <br>dword longint { or cardinal } <br>void* pointer <br>unsigned long longint { or cardinal } <br>bool bool <br>unsigned long int longint { or cardinal } <br>float single <br>[signed] long longint <br>double double <br>[signed] long int longint <br> <br><br> 下面是一些常用和常见数据结构的对照表: <br><br><br>C/C++ Type Object Pascal Type<br><br>handle thandle <br>debughookinfo tdebughookinfo <br>farproc tfarproc <br>bitmapcoreheader tbitmapcoreheader <br>atom tatom <br>bitmapinfoheader tbitmapinfoheader <br>tpoint tpoint <br>bitmapinfo tbitmapinfo <br>trect trect <br>bitmapcoreinfo tbitmapcoreinfo <br>colorref tcolorref <br>bitmapfileheader tbitmapfileheader <br>ofstruct tofstruct <br>ttpolygonheader tpolygonheader <br>handletable thandletable <br>rasterizer_status trasterizer_status <br>bitmap tbitmap <br>mousehookstruct tmousehookstruct <br>rgbtriple trgbtriple <br>cbtactivatestruct tcbtactivatestruct <br>rgbquad trgbquad <br>hardwarehookstruct thardwarehookstruct <br>metarecord tmetarecord <br>eventmsg teventmsg <br>metaheader tmetaheader <br>pattern tpattern { tlogbrush } <br>metafilepict tmetafilepict <br>newtextmetric tnewtextmetric <br>textmetric ttextmetric <br>paletteentry tpaletteentry <br>logbrush tlogbrush <br>logpalette tlogpalette <br>logpen tlogpen <br>kerningpair tkerningpair <br>logfont tlogfont <br>outlinetextmetric toutlinetextmetric <br>enumlogfont tenumlogfont <br>glyphmetrics tglyphmetrics <br>panose tpanose <br>pointfx tpointfx <br>fixed tfixed <br>ttpolycurve tttpolycurve <br>mat2 tmat2 <br>minmaxinfo tminmaxinfo <br>abc tabc <br>paintstruct tpaintstruct <br>wndclass twndclass <br>createstruct tcreatestruct <br>msg tmsg <br>cbt_createwnd tcbt_createwnd <br>seginfo tseginfo <br>measureitemstruct tmeasureitemstruct <br>accel taccel <br>drawitemstruct tdrawitemstruct <br>size tsize <br>deleteitemstruct tdeleteitemstruct <br>dcb tdcb <br>compareitemstruct tcompareitemstruct <br>comstat tcomstat <br>windowpos twindowpos <br>helpwininfo thelpwininfo <br>windowplacement twindowplacement <br>ctlstyle tctlstyle <br>nccalcsize_params tnccalcsize_params <br>ctltype tctltype <br>menuitemtemplateheader tmenuitemtemplateheader <br>ctlinfo tctlinfo <br>menuitemtemplate tmenuitemtemplate <br>ddeadvise tddeadvise <br>mdicreatestruct tmdicreatestruct <br>ddedata tddedata <br>clientcreatestruct tclientcreatestruct <br>ddepoke tddepoke <br>multikeyhelp tmultikeyhelp <br>ddeaack tddeack <br>kanjistruct tkanjistruct <br>devmode 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: 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>这样就可以大大减少手工翻译的时间,而将主要精力用于润色和优化。