怎样在Delphi中调用C++编写的DLL中的函数(100分)

  • 主题发起人 主题发起人 bdw
  • 开始时间 开始时间
B

bdw

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个问题想请教大家;我需要在Delphi中调用由C++编写的DLL中的函数,
函数为bool OmStart(long workModeType,OM_ASYNC_PROC lpAsyncProc,
void *pararm);其中lpAsyncProc是一个回调函数指针,这个回调函数具有
如下原型:void _cdecl async_proc(long pduType, void *pdu, void
*param).回调函数的实现是在Delphi中完成的,pdu是一个非常复杂的结构,
是在C++中的一个头文件中定义的,我想问一下,是否要在Delphi中定义一个
与头文件中完全相同的结构,才能使用访问到Pdu.
 
应该用PASCAL重新定义吧。
 
pdu如果可以为空那就好办,用 nil
不能为空就要自己定义一个对应的pascal的结构,用record
回调函数
void _cdecl async_proc(long pduType, void *pdu, void *param)
在delphi中就是
procedure async_proc(pduType:longint;
pdu:Pointer;
param:Pointer);cdecl;
 
必须从新定义,把原码贴出来,看看有多复杂
 
>我想问一下,是否要在Delphi中定义一个与头文件中完全相同的结构,才能使用访问到Pdu.
不一定,不过记住一点,参数传递的只是指针而已,
指向一块内存区间,
如果结构不完全相同,
所读取的正确部分只是第一个结构中从前向后结构相同的部分。
 
如果要对PDU进行访问和操作,最好重新定义一下。我这里有DrBob写的的
Pascal类型与C类型的转换对应表,贴出来供大家参考一下。
 
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=gb2312">
<meta name="robots" content="noindex,follow">
<meta name="GENERATOR" content="Mozilla/4.51 [en] (Win98;
I) [Netscape]">
<title>HeadConv - C DLL Header Converter</title>
</head>
<body background="back.gif">
<a href="http://drbob42.com/tools/headconv.htm"><img SRC="bologo.gif" BORDER=0 align=RIGHT></a><a href="http://drbob42.com/default.htm" TARGET="_top"><img SRC="bobhoed.gif" BORDER=0 ></a><b><font face="Comic Sans MS"><font size=+3>HeadConv
- C Header Converter
<hr></font></font></b><i>This article shows a tool (<a href="http://www.drbob42.com/ftp/headconv.zip">headconv</a>)
and techniques that can will assist you and enable you to use DLLs written
in foreign languages like C or C++, from within your Delphi applications.</i>
<p>I'm sure you must have experienced it at least once in the past few
months. You've just started to work with Delphi, but wouldn't it be nice
to re-use some of your old C/C++ code. Or wouldn't it be nice to use that
new DLL or API that has just been released, unfortunately with a C header
file. Well, we can use all this old C code, provided we put it in DLLs,
and that also means we can use these foreign DLLs, provided we know what's
in there. A C header file might not be much, but it's often all we have.
And although you might not be able to translate it by hand, this article
will show you ways to (attempt to) translate C DLL header files to Delphi
import units, thereby making it possible for your Delphi apps to call procedures
and functions from this DLL!
<p><b><font size=+2>DLLs</font></b>
<br>Dynamic Link Libraries are - for Windows - the ultimate form of reusable
code. With a DLL, you can create a single library of procedures/functions
or resources that can be used by an unlimited number of applications. DLLs
can be called by any Windows program (or DLL), provided you know how to
ask for the right stuff inside the DLL - you need an import library or
import unit to access the internals.
<p><b><font size=+2>Delphi Import Units</font></b>
<br>Using a C DLL in Delphi is most oftendo
ne by writing an import Unit.
All declarations of the exported routines as well as all types and constants
used or returned by these routines go into the Interface part of the Unit,
the Implementation part only consists of a list of external statements
for the exported routines. In fact all Delphi Units referring to the Windows
API (such as WinProcs, LZExpand, ShellAPI) are examples of such import
units.
<br><i>First of all, what is a Delphi import unit, and howdo
we make one?</i>
<br>You simply put the import units name into your projects uses clause
and the DLL functions are available as if they are defined in some other
Unit of your project.
<br>There are two types of import units: <a href="#implicit">implicit</a>
(static) and <a href="#explicit">explicit</a> (dynamic). It often seems
that an implicit import unit is simpler to write by yourself. However,
the main advantage of dynamically loading DLLs is that your application
can be loaded and run without those DLLs being present, provided that it
can adapt to their absence. For example, if you had implemented a 3D look
in a DLL of your own and couldn't find it (loading it dynamically) then
you could still run the app with the "flat" look. If the DLL in question
had been statically linked, Windows would have refused to run the app (claiming
that your 3D.DLL could not be found), so the user would have been out of
luck.
<br>Another advantage of explicit import units is that the app will initially
load faster because the dynamically loaded DLLs are loaded afterwards on
an as needed basis.
<p><a NAME="implicit"></a><b><font size=+1>Implicit Linking</font></b>
<br><font size=+1>Implicit linking happens when you Use an import unit
for the DLL or declare a DLL function in your code with external 'DLLNAME'.
In this case the linker will place references to the DLL functions into
the imported name table of the produced EXE file and the Windows loader
will automatically load the DLLs (at which time their main block is executed)
with the EXE file:</font>
<pre><font size=+1>&amp;nbsp;<b>procedure</b> Foo(X: Integer);
<b>external</b> 'BAR' <b>index</b> 1;</font></pre>
<font size=+1>If during an implicit link (also called "static link") Windows
cannot find the DLL, you will get a notification - most often a File Error
MessageBox (one thatdo
es <i>not</i> indicate <i>which</i> file is missing,
by the way - most helpful!). So you must be absolutely sure that the DLL
will be available at all times when you want to use implicit import units.</font>
<p><a NAME="explicit"></a><b><font size=+1>Explicit Linking</font></b>
<br><font size=+1>Dynamically linking a DLL using an explicit import unit
is the method VB uses and which you can also use, but "by hand". You load
the DLL when you need it with LoadLibrary, obtain function pointers to
the exported functions you want to use with GetProcAddress and free the
DLL again with FreeLibrary when you no longer need it:</font>
<pre><font size=+1>&amp;nbsp;<b>var
</b>&amp;nbsp;&amp;nbsp;
Hbar: Thandle;
&amp;nbsp;&amp;nbsp;
Foo: <b>procedure</b> (X: Integer);
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}
</i>&amp;nbsp;<b>begin
</b>&amp;nbsp;&amp;nbsp;
Hbar := LoadLibrary('BAR.DLL');
&amp;nbsp;&amp;nbsp;
<b>if</b> Hbar >= 32 <b>then
</b> <i>{ success }
</i>&amp;nbsp;&amp;nbsp;
<b>begin
</b>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Foo := GetProcAddress(HBar, 'FOO');
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Foo(1);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
FreeLibrary(HBar);
&amp;nbsp;&amp;nbsp;
<b>end
</b>&amp;nbsp;&amp;nbsp;
<b>else
</b>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
MessageDlg('Error: could not find BAR.DLL', mtError, [mbOk], 0)
&amp;nbsp;<b>end</b>.</font></pre>
<font size=+1>Note that when we are using an explicit link (also called
"dynamic link"), we can detect whether or not the LoadLibrary failed, and
whether or not the DLL is actually loaded. If the DLL is not loaded, the
program can continue (and just disable the functions or options that needed
the DLL in the first place). This is also one way to write components that
need DLLs, so your Delphi Component Library or Package will still load
if the DLL is not present.</font>
<p><b><font size=+2>C DLL header files</font></b>
<br><font size=+1>Cdo
es not have import units like Delphi, but an optional
static import library (with accompanying header and definition file). From
the C DLL we can generate a static import .LIB file with IMPLIB, and the
.DEF file with IMPDEF (these tools are part of any C/C++ developing environment).
It is the header file that is the most interesting part, since this defines
which functions and which parameters are to be linked in. Most C DLLs will
therefore ship with the .DLL and .H files only (we can regenerate the rest).</font>
<br><font size=+1>To illustrate the task of header conversion, let's check
out a sample C DLL header file, anddo
the conversion by hand. As an example
that everybody will have access to, I choose the WING.H header file from
the 16-bit WING.DLL that Mircosoft provides to developers:</font>
<pre><font size=+1>&amp;nbsp;<i>/*********************************************************************/
&amp;nbsp;*
&amp;nbsp;* wing.h - WinG functions, types, and definitions
&amp;nbsp;*
&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Copyright (c) 1994 Microsoft Corp. All rights reserved.
&amp;nbsp;*
&amp;nbsp;/********************************************************************/
&amp;nbsp;
</i>&amp;nbsp;#ifndef _INC_WING
&amp;nbsp;#define _INC_WING
&amp;nbsp;#ifndef _INC_WINDOWS
&amp;nbsp;#include&amp;nbsp;<windows.h>&amp;nbsp;&amp;nbsp;&amp;nbsp;
<i>/* Include windows.h if not already included */
</i>&amp;nbsp;#endif
&amp;nbsp;#ifdef __cplusplus
&amp;nbsp;extern "C" {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<i>/* Assume C declarations for C++ */
</i>&amp;nbsp;#endif
&amp;nbsp;#if defined(WIN32) || defined(_WIN32)
&amp;nbsp;#define WINGAPI WINAPI
&amp;nbsp;#else
&amp;nbsp;#define WINGAPI WINAPI _loadds
&amp;nbsp;#endif
&amp;nbsp;<i>/***** WingDC and WinGBitmap ****************************************/
</i>&amp;nbsp;HDC WINGAPI WinGCreateDC( void );
&amp;nbsp;BOOL WINGAPI WinGRecommendDIBFormat( BITMAPINFO FAR *pFormat );
&amp;nbsp;HBITMAP WINGAPI WinGCreateBitmap( HDC WinGDC, BITMAPINFO const FAR *pHeader,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
void FAR *FAR *ppBits );
&amp;nbsp;void FAR *WINGAPI WinGGetDIBPointer( HBITMAP WinGBitmap,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
BITMAPINFO FAR *pHeader );
&amp;nbsp;UINT WINGAPI WinGGetDIBColorTable( HDC WinGDC, UINT StartIndex,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
UINT NumberOfEntries, RGBQUAD FAR *pColors );
&amp;nbsp;UINT WINGAPI WinGSetDIBColorTable( HDC WinGDC, UINT StartIndex,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
UINT NumberOfEntries, RGBQUAD const FAR *pColors );
&amp;nbsp;<i>/***** Halftoning ***************************************************/
</i>&amp;nbsp;HPALETTE WINGAPI WinGCreateHalftonePalette( void );
&amp;nbsp;typedef enum WING_DITHER_TYPE
&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DISPERSED_4x4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DISPERSED_8x8,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_CLUSTERED_4x4
&amp;nbsp;} WING_DITHER_TYPE;
&amp;nbsp;HBRUSH WINGAPI WinGCreateHalftoneBrush( HDC Context, COLORREF crColor,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DITHER_TYPE DitherType );
&amp;nbsp;<i>/***** Blts *********************************************************/
</i>&amp;nbsp;BOOL WINGAPI WinGBitBlt( HDC hdcDest, int nXOriginDest,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
int nXOriginSrc, int nYOriginSrc );
&amp;nbsp;BOOL WINGAPI WinGStretchBlt( HDC hdcDest, int nXOriginDest,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc );
&amp;nbsp;#ifdef __cplusplus
&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<i>/* End of extern "C" */
</i>&amp;nbsp;#endif
&amp;nbsp;#endif <i>// _INC_WING</i></font></pre>
<font size=+1>We can conceptually split the DLL in three parts: the first
part contains a lot of compiler directives, the second part contains the
actual function prototypes, and the third part contains some ending compiler
directives (to keep the first part in balance). Let's not worry about the
compiler directives for now, but let's focus on the most important part:
the function prototypes in the second part of the header file.</font>
<p><b><font size=+1>Type Conversion</font></b>
<br><font size=+1>When converting C function prototypes to Pascal equivalent
declarations, it's important to substitute the C function and argument
types with the correct Pascal types. I often use a Type Translation Table
for this, like the following in table 1 (optional parts on the C-side are
noted between square brackets):</font>
<table BORDER=2 >
<tr>
<td BGCOLOR="#A7B7C7">C/C++ Type</td>
<td BGCOLOR="#A7B7C7">ObjectPascal Type</td>
</tr>
<tr>
<td>unsigned short [int]</td>
<td>Word</td>
</tr>
<tr>
<td>[signed] short [int]</td>
<td>SmallInt</td>
</tr>
<tr>
<td>unsigned [int]</td>
<td>Cardinal <i>{ 3.25 fix }</i></td>
</tr>
<tr>
<td>[signed] int</td>
<td>Integer</td>
</tr>
<tr>
<td>UINT</td>
<td>LongInt <i>{ or Cardinal }</i></td>
</tr>
<tr>
<td>WORD</td>
<td>Word</td>
</tr>
<tr>
<td>DWORD</td>
<td>LongInt <i>{ or Cardinal }</i></td>
</tr>
<tr>
<td>unsigned long</td>
<td>LongInt <i>{ or Cardinal }</i></td>
</tr>
<tr>
<td>unsigned long int</td>
<td>LongInt <i>{ or Cardinal }</i></td>
</tr>
<tr>
<td>[signed] long</td>
<td>LongInt</td>
</tr>
<tr>
<td>[signed] long int</td>
<td>LongInt</td>
</tr>
<tr>
<td>char</td>
<td>Char</td>
</tr>
<tr>
<td>signed char</td>
<td>ShortInt</td>
</tr>
<tr>
<td>unsigned char</td>
<td>Byte</td>
</tr>
<tr>
<td>char*</td>
<td>PChar</td>
</tr>
<tr>
<td>LPSTR <i>or PSTR</i></td>
<td>PChar</td>
</tr>
<tr>
<td>LPWSTR <i>or PWSTR</i></td>
<td>PWideChar <i>{ 3.12 fix }</i></td>
</tr>
<tr>
<td>void*</td>
<td>Pointer</td>
</tr>
<tr>
<td>BOOL</td>
<td>Bool</td>
</tr>
<tr>
<td>float</td>
<td>Single</td>
</tr>
<tr>
<td>double</td>
<td>Double</td>
</tr>
<tr>
<td>longdo
uble</td>
<td>Extended</td>
</tr>
<tr>
<td COLSPAN="2" BGCOLOR="#A7B7C7">
<center><i>LP,NP,PP,P prefix: if first = T then
T becomes P else
P prefix&amp;nbsp;</i></center>
</td>
</tr>
<tr>
<td>HANDLE</td>
<td>THandle</td>
</tr>
<tr>
<td>FARPROC</td>
<td>TFarProc</td>
</tr>
<tr>
<td>ATOM</td>
<td>TAtom</td>
</tr>
<tr>
<td>TPOINT</td>
<td>TPoint</td>
</tr>
<tr>
<td>TRECT</td>
<td>TRect</td>
</tr>
<tr>
<td>COLORREF</td>
<td>TColorRef</td>
</tr>
<tr>
<td>OFSTRUCT</td>
<td>TOFStruct</td>
</tr>
<tr>
<td>DEBUGHOOKINFO</td>
<td>TDebugHookInfo</td>
</tr>
<tr>
<td>BITMAP</td>
<td>TBitMap</td>
</tr>
<tr>
<td>RGBTRIPLE</td>
<td>TRGBTriple</td>
</tr>
<tr>
<td>RGBQUAD</td>
<td>TRGBQuad</td>
</tr>
<tr>
<td>BITMAPCOREHEADER</td>
<td>TBitmapCoreHeader</td>
</tr>
<tr>
<td>BITMAPINFOHEADER</td>
<td>TBitmapInfoHeader</td>
</tr>
<tr>
<td>BITMAPINFO</td>
<td>TBitmapInfo</td>
</tr>
<tr>
<td>BITMAPCOREINFO</td>
<td>TBitmapCoreInfo</td>
</tr>
<tr>
<td>BITMAPFILEHEADER</td>
<td>TBitmapFileHeader</td>
</tr>
<tr>
<td>HANDLETABLE</td>
<td>THandleTable</td>
</tr>
<tr>
<td>METARECORD</td>
<td>TMetaRecord</td>
</tr>
<tr>
<td>METAHEADER</td>
<td>TMetaHeader</td>
</tr>
<tr>
<td>METAFILEPICT</td>
<td>TMetaFilePict</td>
</tr>
<tr>
<td>TEXTMETRIC</td>
<td>TTextMetric</td>
</tr>
<tr>
<td>NEWTEXTMETRIC</td>
<td>TNewTextMetric</td>
</tr>
<tr>
<td>LOGBRUSH</td>
<td>TLogBrush</td>
</tr>
<tr>
<td>LOGPEN</td>
<td>TLogPen</td>
</tr>
<tr>
<td>PATTERN</td>
<td>TPattern { TLogBrush }</td>
</tr>
<tr>
<td>PALETTEENTRY</td>
<td>TPaletteEntry</td>
</tr>
<tr>
<td>LOGPALETTE</td>
<td>TLogPalette</td>
</tr>
<tr>
<td>LOGFONT</td>
<td>TLogFont</td>
</tr>
<tr>
<td>ENUMLOGFONT</td>
<td>TEnumLogFont</td>
</tr>
<tr>
<td>PANOSE</td>
<td>TPanose</td>
</tr>
<tr>
<td>KERNINGPAIR</td>
<td>TKerningPair</td>
</tr>
<tr>
<td>OUTLINETEXTMETRIC</td>
<td>TOutlineTextMetric</td>
</tr>
<tr>
<td>FIXED</td>
<td>TFixed</td>
</tr>
<tr>
<td>MAT2</td>
<td>TMat2</td>
</tr>
<tr>
<td>GLYPHMETRICS</td>
<td>TGlyphMetrics</td>
</tr>
<tr>
<td>POINTFX</td>
<td>TPointFX</td>
</tr>
<tr>
<td>TTPOLYCURVE</td>
<td>TTTPolyCurve</td>
</tr>
<tr>
<td>TTPOLYGONHEADER</td>
<td>TPolygonHeader</td>
</tr>
<tr>
<td>ABC</td>
<td>TABC</td>
</tr>
<tr>
<td>RASTERIZER_STATUS</td>
<td>TRasterizer_Status</td>
</tr>
<tr>
<td>MOUSEHOOKSTRUCT</td>
<td>TMouseHookStruct</td>
</tr>
<tr>
<td>CBTACTIVATESTRUCT</td>
<td>TCBTActivateStruct</td>
</tr>
<tr>
<td>HARDWAREHOOKSTRUCT</td>
<td>THardwareHookStruct</td>
</tr>
<tr>
<td>EVENTMSG</td>
<td>TEventMsg</td>
</tr>
<tr>
<td>WNDCLASS</td>
<td>TWndClass</td>
</tr>
<tr>
<td>MSG</td>
<td>TMsg</td>
</tr>
<tr>
<td>MINMAXINFO</td>
<td>TMinMaxInfo</td>
</tr>
<tr>
<td>SEGINFO</td>
<td>TSegInfo</td>
</tr>
<tr>
<td>ACCEL</td>
<td>TAccel</td>
</tr>
<tr>
<td>PAINTSTRUCT</td>
<td>TPaintStruct</td>
</tr>
<tr>
<td>CREATESTRUCT</td>
<td>TCreateStruct</td>
</tr>
<tr>
<td>CBT_CREATEWND</td>
<td>TCBT_CreateWnd</td>
</tr>
<tr>
<td>MEASUREITEMSTRUCT</td>
<td>TMeasureItemStruct</td>
</tr>
<tr>
<td>DRAWITEMSTRUCT</td>
<td>TDrawItemStruct</td>
</tr>
<tr>
<td>DELETEITEMSTRUCT</td>
<td>TDeleteItemStruct</td>
</tr>
<tr>
<td>COMPAREITEMSTRUCT</td>
<td>TCompareItemStruct</td>
</tr>
<tr>
<td>WINDOWPOS</td>
<td>TWindowPos</td>
</tr>
<tr>
<td>WINDOWPLACEMENT</td>
<td>TWindowPlacement</td>
</tr>
<tr>
<td>NCCALCSIZE_PARAMS</td>
<td>TNCCalcSize_Params</td>
</tr>
<tr>
<td>SIZE</td>
<td>TSize</td>
</tr>
<tr>
<td>MENUITEMTEMPLATEHEADER</td>
<td>TMenuItemTemplateHeader</td>
</tr>
<tr>
<td>MENUITEMTEMPLATE</td>
<td>TMenuItemTemplate</td>
</tr>
<tr>
<td>DCB</td>
<td>TDCB</td>
</tr>
<tr>
<td>COMSTAT</td>
<td>TComStat</td>
</tr>
<tr>
<td>MDICREATESTRUCT</td>
<td>TMDICreateStruct</td>
</tr>
<tr>
<td>CLIENTCREATESTRUCT</td>
<td>TClientCreateStruct</td>
</tr>
<tr>
<td>MULTIKEYHELP</td>
<td>TMultiKeyHelp</td>
</tr>
<tr>
<td>HELPWININFO</td>
<td>THelpWinInfo</td>
</tr>
<tr>
<td>CTLSTYLE</td>
<td>TCtlStyle</td>
</tr>
<tr>
<td>CTLtype</td>
<td>TCtltype</td>
</tr>
<tr>
<td>CTLINFO</td>
<td>TCtlInfo</td>
</tr>
<tr>
<td>DDEADVISE</td>
<td>TDDEAdvise</td>
</tr>
<tr>
<td>DDEDATA</td>
<td>TDDEData</td>
</tr>
<tr>
<td>DDEPOKE</td>
<td>TDDEPoke</td>
</tr>
<tr>
<td>DDEAACK</td>
<td>TDDEAck</td>
</tr>
<tr>
<td>DEVMODE</td>
<td>TDevMode</td>
</tr>
<tr>
<td>KANJISTRUCT</td>
<td>TKanjiStruct</td>
</tr>
</table>
<p><font size=+1>It's also nice to have access to the translation of the
special WINDOWS.H types, which is alreadydo
ne by Borland, and can be found
in WINTYPES.PAS (it's a rewarding experience to compare these two files
with each other - you'll learn a lot about C and Pascal conversion issues).</font>
<br><font size=+1>Now that we've handled the standard built-in (and Windows)
types, let's look at the C type definition of WING_DITHER_TYPE that is
present in the WING.H file.</font>
<pre><font size=+1>&amp;nbsp;<b>typedef</b> <b>enum</b> WING_DITHER_TYPE
&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DISPERSED_4x4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DISPERSED_8x8,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_CLUSTERED_4x4
&amp;nbsp;} WING_DITHER_TYPE;</font></pre>
<font size=+1>This is a so -called enumerated type, and can be translated
into an ObjectPascal enumerated type very easily:</font>
<pre><font size=+1>&amp;nbsp;<b>Type
</b>&amp;nbsp;&amp;nbsp;
WING_DITHER_TYPE =
&amp;nbsp;&amp;nbsp;&amp;nbsp;
(WING_DISPERSED_4x4,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_DISPERSED_8x8,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WING_CLUSTERED_4x4);</font></pre>
<font size=+1>While most C DLL header files contain only constant definitions
(of the form #define XYZ value) and function prototypes, type definitions
are also found, and are therefore important to be able to convert.</font>
<p><b><font size=+1>C Functions</font></b>
<br><font size=+1>Now that we've seen C to Pascal type conversion, we can
start to convert a few of the functions that are defined in the C header
file, like the WinGCreateDC function:</font>
<pre><font size=+1>&amp;nbsp;HDC WINGAPI WinGCreateDC( void );</font></pre>
<font size=+1>Clearly, it is a function and not a procedure, since it has
a non-void return type. The function has no arguments, and hence the implicit
ObjectPascal equivalent declaration is as follows:</font>
<pre><font size=+1>&amp;nbsp;<b>function</b> WinGCreateDC: HDC;
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}
</i>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<b>external</b> 'WING' <b>index</b> 1001;</font></pre>
<font size=+1>The index number can be obtained from the .DEF file, by the
way. If youdo
not have access to the .DEF file, and IMPDEF is not available
to generate one from the .DLL, then
you can just omit the index part. The
function will still link implicitly, but will load somewhat slower (since
the loader will have to search for it by name instead of by number).</font>
<br><font size=+1>The equivalent explicit declaration is as follows:</font>
<pre><font size=+1>&amp;nbsp;<b>var</b> WinGCreateDC: <b>function</b>: HDC;
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}</i></font></pre>
<font size=+1>Where we have to make sure todo
a GetProcAddress of WinGCreateDC
after the LoadLibrary was successful (see also the earlier explicit linking
example).</font>
<br><font size=+1>Other WinG functions thatdo
have arguments can be translated
accordingly, for example the WinGRecommendedDIBFormat, WinGCreateBitmap
and WinGCreateHalftoneBrush. Note that the last one actually uses a translated
custom type WING_DITHER_TYPE that we generated in the C to Pascal Type
Conversion section.</font>
<pre><font size=+1>&amp;nbsp;<b>function</b> WinGRecommendDIBFormat(pFormat: PBitmapInfo): Bool;
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}
</i>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<b>external</b> 'WING' <b>index</b> 1002;
&amp;nbsp;<b>function</b> WinGCreateBitmap(WinGDC: HDC;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Const pHeader: PBitmapInfo;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ppBits: PPointer): HBITMAP;
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}
</i>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<b>external</b> 'WING' <b>index</b> 1003;
&amp;nbsp;<b>function</b> WinGCreateHalftoneBrush(Context: HDC;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
crColor: TColorRef;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DitherType: WING_DITHER_TYPE): HBRUSH;
<i>{$IFDEF WIN32} stdcall;
{$ENDIF}
</i>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
<b>external</b> 'WING' <b>index</b> 1008;</font></pre>
<font size=+1>Please also note that these last three function conversions
are for use in an implicit import unit, not an explicit one.</font>
<p><b><font size=+1>Compiler Directives</font></b>
<br><font size=+1>As I've said, compiler directives are the last and often
most difficult task to convert. It's often important to keep in mind what
the target of the converted unit will be - win16 or win32 for example,
so you can eliminate a lot of conversions will you're scanning compiler
directives (you won't need to convert everything in the #ifdef WIN32 section
if you are working on a 16-bit import unit only, of course.</font>
<p><b><font size=+2>Tool Support - HeadConv</font></b>
<br><font size=+1>So far, we have seen that part of the conversion process
is easy, part of it is hard, and a lot of it is simple 'monkey' work, that
is neither complex nor particularly rewarding todo
. In order to support
myself in the monkey-work, I've written a little program to help me: HeadConv.
Targeted at the serious Delphi developer, the HeadConv Expert will assist
in the task of converting the C DLL header files to Delphi import units,
thereby giving all Delphi users access to the huge world of third-party
C DLLs.</font>
<center>
<p><img SRC="headcnv1.gif" >
<br><i><font size=+1>Figure 1. HeadConv Main Page</font></i></center>
<p><font size=+1>As an example, the converted WING.H header file is used.
The new file WING.PAS did only require two additional little changes in
the source code (at two compiler directives) and instantly recompiled.
Please note that with other (more complex) header files, some extra modifications
might be necessary to get the same results.</font>
<center>
<p><img SRC="headcnv2.gif" >
<br><i><font size=+1>Figure 2. HeadConv Type Page</font></i></center>
<p><font size=+1>HeadConv has full support for functions and procedures,
argument and return types (it has a Type Translation Table of up to 128
custom type conversions - see figure 2) and generates implicit Delphi import
units. The expert is integrated in the Delphi IDE, making the conversion
very easy as the converted file is opened up in the IDE automatically.
HeadConv is not targeted todo
the conversion 100% on its own, rather it
will assist in converting the C DLL header files!</font>
<center>
<p><img SRC="headcnv3.gif" >
<br><i><font size=+1>Figure 3. HeadConv About Page</font></i></center>
<p><font size=+1>The <i>HeadConv About Page</i> above is outdated: ever
since the <b>Delphi Jedi Project</b> started, the use of HeadConv has been
free for everyone. The only restriction is that Ido
n't publish the source
code of HeadConv itself, and I expect all problems and comments to be posted
in my special "headconv" newsgroup at <a href="news://news.shoresoft.com/drbob.wizards.headconv">drbob.wizards.headconv</a>.</font>
<p>
<hr>
<center><font face="Comic Sans MS"><font color="#CC0000"><font size=-2>This
webpage (C) 2000 by webmaster drs. Robert E. Swart (aka <a href="mailto:drbob@chello.nl">Dr.Bob</a>
- <a href="http://www.drbob42.com" TARGET="_top">www.drbob42.com</a>).
All Rights Reserved.</font></font></font></center>
</body>
</html>
 
多人接受答案了。
 
后退
顶部