求教Dll在Delphi中的声明 (100分)

  • 主题发起人 主题发起人 foxyxyan
  • 开始时间 开始时间
F

foxyxyan

Unregistered / Unconfirmed
GUEST, unregistred user!
void SPacket3Des(const char* pszSrc, char* pszDest, long &amp; nLen, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const char *pszKey1, const char *pszKey2, int nMode);<br>这是用c写的Dll,想在Delphi中调用,但是声明后调用出错,不知是否自己的声明有误。<br>procedure SPacket3Des(pszSrc: pChar;pszDest: pChar; nLen :integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pszKey1: pChar;pszKey2:pChar;nMode:integer);<br>这是我自己写的声明。请诸位勘误,指点。<br>
 
这里有篇资料,你参考一下<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>   &nbsp; &nbsp;Hbar := LoadLibrary('BAR.DLL');<br>   &nbsp; &nbsp;if Hbar 〉= 32 then { success } begin<br>&nbsp; &nbsp; &nbsp;    Foo := GetProcAddress(HBar, 'FOO');<br>&nbsp;   &nbsp; &nbsp; &nbsp; ... <br>   &nbsp; &nbsp; &nbsp; Foo(1); <br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;...<br>   &nbsp; &nbsp; &nbsp; FreeLibrary(HBar); <br>   &nbsp; &nbsp;end<br>   &nbsp; &nbsp;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>&nbsp;  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>&nbsp;Object Pascal Type<br>&nbsp;C/C++ Type<br>&nbsp;Object Pascal Type<br>&nbsp;<br>unsigned short [int]<br>&nbsp;word <br>&nbsp;char <br>&nbsp;char <br>&nbsp;<br>[signed] short [int] <br>&nbsp;smallint <br>&nbsp;signed char <br>&nbsp;shortint <br>&nbsp;<br>unsigned [int] <br>&nbsp;cardinal { 3.25 fix } <br>&nbsp;unsigned char <br>&nbsp;byte <br>&nbsp;<br>[signed] int <br>&nbsp;integer <br>&nbsp;char* <br>&nbsp;pchar <br>&nbsp;<br>uint <br>&nbsp;longint { or cardinal } <br>&nbsp;lpstr or pstr <br>&nbsp;pchar <br>&nbsp;<br>word <br>&nbsp;word <br>&nbsp;lpwstr or pwstr <br>&nbsp;pwidechar { 3.12 fix } <br>&nbsp;<br>dword <br>&nbsp;longint { or cardinal } <br>&nbsp;void* <br>&nbsp;pointer <br>&nbsp;<br>unsigned long <br>&nbsp;longint { or cardinal } <br>&nbsp;bool <br>&nbsp;bool <br>&nbsp;<br>unsigned long int <br>&nbsp;longint { or cardinal } <br>&nbsp;float <br>&nbsp;single <br>&nbsp;<br>[signed] long <br>&nbsp;longint <br>&nbsp;double <br>&nbsp;double <br>&nbsp;<br>[signed] long int <br>&nbsp;longint <br>&nbsp;    <br><br>  下面是一些常用和常见数据结构的对照表: <br><br><br>C/C++ Type<br>&nbsp;Object Pascal Type<br>&nbsp;C/C++ Type<br>&nbsp;Object Pascal Type<br>&nbsp;<br>handle<br>&nbsp; &nbsp;thandle <br>&nbsp;debughookinfo <br>&nbsp;tdebughookinfo <br>&nbsp;<br>farproc <br>&nbsp;tfarproc <br>&nbsp;bitmapcoreheader <br>&nbsp;tbitmapcoreheader <br>&nbsp;<br>atom <br>&nbsp;tatom <br>&nbsp;bitmapinfoheader <br>&nbsp;tbitmapinfoheader <br>&nbsp;<br>tpoint <br>&nbsp;tpoint <br>&nbsp;bitmapinfo <br>&nbsp;tbitmapinfo <br>&nbsp;<br>trect <br>&nbsp;trect <br>&nbsp;bitmapcoreinfo <br>&nbsp;tbitmapcoreinfo <br>&nbsp;<br>colorref <br>&nbsp;tcolorref <br>&nbsp;bitmapfileheader <br>&nbsp;tbitmapfileheader <br>&nbsp;<br>ofstruct <br>&nbsp;tofstruct <br>&nbsp;ttpolygonheader <br>&nbsp;tpolygonheader <br>&nbsp;<br>handletable <br>&nbsp;thandletable <br>&nbsp;rasterizer_status <br>&nbsp;trasterizer_status <br>&nbsp;<br>bitmap <br>&nbsp;tbitmap <br>&nbsp;mousehookstruct <br>&nbsp;tmousehookstruct <br>&nbsp;<br>rgbtriple <br>&nbsp;trgbtriple <br>&nbsp;cbtactivatestruct <br>&nbsp;tcbtactivatestruct <br>&nbsp;<br>rgbquad <br>&nbsp;trgbquad <br>&nbsp;hardwarehookstruct <br>&nbsp;thardwarehookstruct <br>&nbsp;<br>metarecord <br>&nbsp;tmetarecord <br>&nbsp;eventmsg <br>&nbsp;teventmsg <br>&nbsp;<br>metaheader <br>&nbsp;tmetaheader <br>&nbsp;pattern <br>&nbsp;tpattern { tlogbrush } <br>&nbsp;<br>metafilepict <br>&nbsp;tmetafilepict <br>&nbsp;newtextmetric <br>&nbsp;tnewtextmetric <br>&nbsp;<br>textmetric <br>&nbsp;ttextmetric <br>&nbsp;paletteentry <br>&nbsp;tpaletteentry <br>&nbsp;<br>logbrush <br>&nbsp;tlogbrush <br>&nbsp;logpalette <br>&nbsp;tlogpalette <br>&nbsp;<br>logpen <br>&nbsp;tlogpen <br>&nbsp;kerningpair <br>&nbsp;tkerningpair <br>&nbsp;<br>logfont <br>&nbsp;tlogfont <br>&nbsp;outlinetextmetric <br>&nbsp;toutlinetextmetric <br>&nbsp;<br>enumlogfont <br>&nbsp;tenumlogfont <br>&nbsp;glyphmetrics <br>&nbsp;tglyphmetrics <br>&nbsp;<br>panose <br>&nbsp;tpanose <br>&nbsp;pointfx <br>&nbsp;tpointfx <br>&nbsp;<br>fixed <br>&nbsp;tfixed <br>&nbsp;ttpolycurve <br>&nbsp;tttpolycurve <br>&nbsp;<br>mat2 <br>&nbsp;tmat2 <br>&nbsp;minmaxinfo <br>&nbsp;tminmaxinfo <br>&nbsp;<br>abc <br>&nbsp;tabc <br>&nbsp;paintstruct <br>&nbsp;tpaintstruct <br>&nbsp;<br>wndclass <br>&nbsp;twndclass <br>&nbsp;createstruct <br>&nbsp;tcreatestruct <br>&nbsp;<br>msg <br>&nbsp;tmsg <br>&nbsp;cbt_createwnd <br>&nbsp;tcbt_createwnd <br>&nbsp;<br>seginfo <br>&nbsp;tseginfo <br>&nbsp;measureitemstruct <br>&nbsp;tmeasureitemstruct <br>&nbsp;<br>accel <br>&nbsp;taccel <br>&nbsp;drawitemstruct <br>&nbsp;tdrawitemstruct <br>&nbsp;<br>size <br>&nbsp;tsize <br>&nbsp;deleteitemstruct <br>&nbsp;tdeleteitemstruct <br>&nbsp;<br>dcb <br>&nbsp;tdcb <br>&nbsp;compareitemstruct <br>&nbsp;tcompareitemstruct <br>&nbsp;<br>comstat <br>&nbsp;tcomstat <br>&nbsp;windowpos <br>&nbsp;twindowpos <br>&nbsp;<br>helpwininfo <br>&nbsp;thelpwininfo <br>&nbsp;windowplacement <br>&nbsp;twindowplacement <br>&nbsp;<br>ctlstyle <br>&nbsp;tctlstyle <br>&nbsp;nccalcsize_params <br>&nbsp;tnccalcsize_params <br>&nbsp;<br>ctltype <br>&nbsp;tctltype <br>&nbsp;menuitemtemplateheader <br>&nbsp;tmenuitemtemplateheader <br>&nbsp;<br>ctlinfo <br>&nbsp;tctlinfo <br>&nbsp;menuitemtemplate <br>&nbsp;tmenuitemtemplate <br>&nbsp;<br>ddeadvise <br>&nbsp;tddeadvise <br>&nbsp;mdicreatestruct <br>&nbsp;tmdicreatestruct <br>&nbsp;<br>ddedata <br>&nbsp;tddedata <br>&nbsp;clientcreatestruct <br>&nbsp;tclientcreatestruct <br>&nbsp;<br>ddepoke <br>&nbsp;tddepoke <br>&nbsp;multikeyhelp <br>&nbsp;tmultikeyhelp <br>&nbsp;<br>ddeaack <br>&nbsp;tddeack <br>&nbsp;kanjistruct <br>&nbsp;tkanjistruct <br>&nbsp;<br>devmode <br>&nbsp;tdevmode <br>&nbsp;    <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>这样就可以大大减少手工翻译的时间,而将主要精力用于润色和优化。
 
應該是定義的參數類型不一樣,可否把你調用的過程改為和c中定義的格式一樣。<br>procedure SPacket3Des(const pszSrc: pChar;pszDest: pChar; nLen :integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;const pszKey1: pChar;const pszKey2:pChar;nMode:integer);<br>
 
试了一下:<br>&nbsp; 声明:procedure SPacket3Des(const pszSrc:pChar; pszDest:pChar;nLen:longint;<br> &nbsp; &nbsp; &nbsp; &nbsp;const pszKey1:pChar;const pszKey2:pChar;nMode:integer); stdcall;external 'xxxxxx.dll' name 'SPacket3Des' ;<br>&nbsp; 例子:var S,Key1,Key2:String;<br>&nbsp; &nbsp; &nbsp; &nbsp; S := 'Test'; Key1 := '12345678';Key2 :='12345678';<br>&nbsp; &nbsp; &nbsp; &nbsp; Spacket3Des(pChar(s),pChar(s),length(s),pchar(key1),pchar(key2),0);//报错。<br>&nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; <br>
 
多人接受答案了。
 
后退
顶部