📄 ch28.htm
字号:
help is a good source of information for these three DLLs.</P>
<P>A good tool for poking around in Windows applications is the DumpBin utility,
usually found in \Program Files\Microsoft Visual Studio\VC98\Bin. DumpBin is a command
line program that shows you the imports and exports of executable files and dynamic
link libraries. The following listing is an excerpted example of the output produced
when using DumpBin to examine the executable file for Spy++, one of the utilities
provided with Visual C++.</P>
<P>
<H4>Listing 28.3  Output from DumpBin</H4>
<PRE>dumpbin -imports spyxx.exe
Microsoft (R) COFF Binary File Dumper Version 6.00.8047
Copyright Microsoft Corp 1992-1998. All rights reserved.
Dump of file spyxx.exe
File Type: EXECUTABLE IMAGE
Section contains the following imports:
MFC42.DLL
44B138 Import Address Table
452B8C Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 818
Ordinal 4424
... 392 similar lines omitted ...
MSVCRT.dll
44B7A4 Import Address Table
4531F8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
81 __set_app_type
6F __p__fmode
6A __p__commode
9D _adjust_fdiv
83 __setusermatherr
10F _initterm
58 __getmainargs
8F _acmdln
249 exit
2B5 sscanf
49 __CxxFrameHandler
298 memmove
1B9 _splitpath
134 _itoa
159 _mbscmp
2C9 strtoul
100 _getmbcp
168 _mbsnbcpy
8E _access
161 _mbsinc
192 _purecall
2B2 sprintf
A5 _beginthread
C4 _endthread
25E free
15F _mbsicmp
B7 _controlfp
291 malloc
158 _mbschr
F1 _ftol
1F3 _wcsupr
2EB wcsrchr
63 __p___argv
62 __p___argc
2D4 toupper
272 iscntrl
2D0 time
55 __dllonexit
186 _onexit
CA _except_handler3
2E ?terminate@@YAXXZ
D3 _exit
48 _XcptFilter
1AA _setmbcp
MSVCIRT.dll
44B75C Import Address Table
4531B0 Import Name Table
0 time date stamp
0 Index of first forwarder reference
194 ?str@strstreambuf@@QAEPADXZ
11F ?freeze@strstreambuf@@QAEXH@Z
10F ?ends@@YAAAVostream@@AAV1@@Z
171 ?seekp@ostream@@QAEAAV1@J@Z
8B ??6ostream@@QAEAAV0@K@Z
87 ??6ostream@@QAEAAV0@G@Z
50 ??1ostrstream@@UAE@XZ
14 ??0ios@@IAE@XZ
31 ??0ostrstream@@QAE@XZ
1BB _mtlock
1BC _mtunlock
47 ??1ios@@UAE@XZ
8A ??6ostream@@QAEAAV0@J@Z
89 ??6ostream@@QAEAAV0@I@Z
88 ??6ostream@@QAEAAV0@H@Z
85 ??6ostream@@QAEAAV0@E@Z
93 ??6ostream@@QAEAAV0@PBD@Z
KERNEL32.dll
44B084 Import Address Table
452AD8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
246 SetEvent
136 GetProfileStringA
10F GetModuleFileNameA
32 CreateFileA
19 CloseHandle
2AC WideCharToMultiByte
1CB MultiByteToWideChar
93 FindResourceA
272 SizeofResource
168 GlobalAlloc
173 GlobalLock
1AE LoadResource
1BC LockResource
17A GlobalUnlock
16F GlobalFree
... 29 similar lines omitted ...
USER32.dll
44B8AC Import Address Table
453300 Import Name Table
0 time date stamp
0 Index of first forwarder reference
2A5 wsprintfA
160 GetWindowWord
253 SetWindowLongA
158 GetWindowPlacement
1CF OffsetRect
189 IsIconic
16E InflateRect
240 SetRectEmpty
CF EnumWindows
BC EnumChildWindows
218 SetActiveWindow
EE GetClientRect
... 77 similar lines omitted ...
GDI32.dll
44B024 Import Address Table
452A78 Import Name Table
0 time date stamp
0 Index of first forwarder reference
167 Rectangle
121 GetStockObject
17A SelectObject
3D CreatePen
19D SetROP2
30 CreateFontIndirectA
36 CreateHatchBrush
41 CreateRectRgn
72 FrameRgn
1D CreateBitmap
E8 GetDeviceCaps
137 GetTextMetricsA
130 GetTextExtentPoint32A
3C CreatePatternBrush
14E PatBlt
161 PtInRegion
46 CreateSolidBrush
4C DeleteObject
111 GetObjectA
23 CreateCompatibleDC
D BitBlt
118 GetPixel
6B ExtTextOutA
ADVAPI32.dll
44B000 Import Address Table
452A54 Import Name Table
0 time date stamp
0 Index of first forwarder reference
148 RegCreateKeyA
15B RegOpenKeyA
160 RegQueryInfoKeyA
149 RegCreateKeyExA
170 RegSetValueExA
15C RegOpenKeyExA
165 RegQueryValueExA
145 RegCloseKey
Summary
17000 .data
A000 .rdata
10000 .rsrc
</PRE>
<PRE> 4A000 .text
</PRE>
<P>As you can see, the utility program Spy++ uses the C Runtime and Windows DLLs
extensively.</P>
<P>You can call functions from the Windows DLLs in any of your programs, and more
importantly, you can write DLLs of your own.</P>
<P>
<H3><A NAME="Heading6"></A>Making a 32-Bit DLL</H3>
<P>There are two kinds of DLLs in Visual C++: Those that use MFC and those that don't.
Each kind of DLL has its own AppWizard, as you will see shortly.</P>
<P>If you gather three or four functions into a DLL, your DLL <I>exports</I> those
functions for other programs to use. Quite often a DLL will also <I>import</I> functions
from other DLLs to get its work done.</P>
<P><B>Importing and Exporting Functions  </B>To designate a symbol as exportable,
use the following syntax:</P>
<P>
<PRE>__declspec(dllexport) data_type int var_name; // for variables
</PRE>
<P>or</P>
<P>
<PRE>__declspec(ddlexport) return_type func_name( [argument_list ] );
// for functions
</PRE>
<P>Importing functions is almost identical: Simply replace the keyword tokens, __declspec(dllexport)
with __declspec(dllimport). Use an actual function and variable to demonstrate the
syntax this time:</P>
<P>
<PRE>__declspec(dllimport) int referenceCount;
__declspec(dllimport) void DiskFree( lpStr Drivepath );
</PRE>
<BLOCKQUOTE>
<P>
<HR>
<STRONG>TIP:</STRONG> Two underscores precede the keyword __declspec.
<HR>
</BLOCKQUOTE>
<P>By convention, Microsoft uses a header file and a preprocessor macro to make the
inclusion of DLL declarations much simpler. The technique requires that you make
a preprocessor token using a unique token--the header filename works easily and requires
very little in the way of memorization--and define a macro that will replace the
token with the correct import or export statement. Thus, assuming a header file named
Diskfree.h, the preprocessor macro in the header file would be as follows.</P>
<P>
<H4>Listing 28.4  Diskfree.h</H4>
<PRE>// DISKFREE.H - Contains a simpler function for returning the amount of
// free disk space.
#ifndef __DISKFREE_H
#define __DISKFREE_H
#ifndef __DISKFREE__
#define DISKFREELIB __declspec(dllimport)
#else
#define DISKFREELIB __declspec(dllexport)
#endif
// Use the macro to control an import or export declaration.
DISKFREELIB unsigned long DiskFree( unsigned int drive );
// (e.g. 0 = A:, 1 = B:, 2 = C:
</PRE>
<PRE>#endif
</PRE>
<P>By including the header file, you can let the preprocessor decide whether DiskFree
is being imported or exported. Now you can share the header file for the DLL developer
and the DLL user, and that means fewer maintenance headaches.</P>
<P><B>Creating the DiskFree DLL  </B>The DiskFree utility provides a simple
way to determine the amount of free disk space for any given drive. The underlying
functionality is the GetDiskFreeSpace() function found in Kernel32.dll.</P>
<P>To create a non-MFC DLL, choose File, New, click the Projects tab, select Win32
Dynamic Link Library from the list on the left, and enter DiskFree for the project
name. Click OK and the AppWizard dialog box, shown in Figure 28.4, appears. Choose
An Empty DLL project, and your project is created with no files in it.</P>
<P>Add a C++ header file called DiskFree.h to the project and type in the code from
Listing 28.5. Add a C++ source file called DiskFree.cpp and type in the code from
Listing 28.6.</P>
<P>
<H4>Listing 28.5  DiskFree.h</H4>
<PRE>#ifndef __DISKFREE_H
#define __DISKFREE_H
#ifndef __DISKFREE__
#define __DISKFREELIB__ __declspec(dllimport)
#else
#define __DISKFREELIB__ __declspec(dllexport)
#endif
// Returns the amount of free space on drive number (e.g. 0 = A:, 1= B:,
// 2 = c:)
__DISKFREELIB__ unsigned long DiskFree( unsigned int drive );
</PRE>
<PRE>#endif
</PRE>
<H4>Listing 28.6   DiskFree.cpp</H4>
<PRE>#include <afx.h>
#include <winbase.h> // Declares kernel32 GetDiskFreeSpace
#define __DISKFREE__ // Define the token before including the library
#include "diskfree.h"
// Returns the amount of free space on drive number
// (e.g. 0 = A:, 1= B:, 2 = c:)
__DISKFREELIB__ unsigned long DiskFree( unsigned int drive )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -