Dll的作用就不用多说了吧?动态链接库,可以封装函数、变量、类库等数据,为外部实现透明调用。
1. 将函数封装进dll文件中:
使用Codeblocks新建一个名为testDll的Dynamic Link Library项目,默认会生成一个.cpp和一个.h文件,里面有基本的代码,修改如下:
main.h
注意定义
DLL_EXPORT的时候要加上
extern "C",不然是找不到函数的。
main.cpp:
其中函数addxy是我定义的测试函数,前面加的
DLL_EXPORT声明是main.h中定义的函数说明。
然后编译类型选Release,编译通过后,在bin/Release目录下生成了一个testDll.dll的动态链接库文件。如果 编译类型选Debug的话,编译出来的函数比较奇怪,这个可以分别从 Release和Debug文件夹中的libtestDll.def文件看出来。 使用VS2005所带的dumpbin命令可以看出 libtestDll.dll的内容:
输入
可以看到如下输出:
从中可以看出我们定义的addxy函数。
到此为止,动态库已经完成。
2. 下面要做的是写一个测试程序来调用刚才生成的testDll.dll文件。
新建一个名为callDll的Console appliation项目,修改main.c代码如下:
编译,并将1中
bin/Release目录下生成了testDll.dll
文件拷贝到callDll项目的目录下,运行即可输出结果。说明调用成功。
1. 将函数封装进dll文件中:
使用Codeblocks新建一个名为testDll的Dynamic Link Library项目,默认会生成一个.cpp和一个.h文件,里面有基本的代码,修改如下:
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include < windows.h >
#include < stdio.h >
#include < stdlib.h >
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL
#define DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define DLL_EXPORT extern "C" __declspec(dllimport)
#endif
DLL_EXPORT int addxy( int a, int b );
#endif // __MAIN_H__
#define __MAIN_H__
#include < windows.h >
#include < stdio.h >
#include < stdlib.h >
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL
#define DLL_EXPORT extern "C" __declspec(dllexport)
#else
#define DLL_EXPORT extern "C" __declspec(dllimport)
#endif
DLL_EXPORT int addxy( int a, int b );
#endif // __MAIN_H__
main.cpp:
#include
"
main.h
"
// test here
DLL_EXPORT int addxy( int a, int b )
{
return (a+b);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}
// test here
DLL_EXPORT int addxy( int a, int b )
{
return (a+b);
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
}
return TRUE; // succesful
}
然后编译类型选Release,编译通过后,在bin/Release目录下生成了一个testDll.dll的动态链接库文件。如果 编译类型选Debug的话,编译出来的函数比较奇怪,这个可以分别从 Release和Debug文件夹中的libtestDll.def文件看出来。 使用VS2005所带的dumpbin命令可以看出 libtestDll.dll的内容:
输入
dumpbin
/
exports testDll.dll
D:My DocumentswxWidgets estcallDll
>
dumpbin
/
exports testDll_r1.dll
Microsoft (R) COFF / PE Dumper Version 8.00 . 50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file testDll_r1.dll
File Type: DLL
Section contains the following exports for testDll.dll
00000000 characteristics
477CD664 time date stamp Thu Jan 03 20 : 34 : 44 2008
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001180 addxy
Summary
1000 .bss
1000 .data
1000 .edata
1000 .idata
1000 .rdata
1000 .reloc
1000 .text
Microsoft (R) COFF / PE Dumper Version 8.00 . 50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file testDll_r1.dll
File Type: DLL
Section contains the following exports for testDll.dll
00000000 characteristics
477CD664 time date stamp Thu Jan 03 20 : 34 : 44 2008
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001180 addxy
Summary
1000 .bss
1000 .data
1000 .edata
1000 .idata
1000 .rdata
1000 .reloc
1000 .text
到此为止,动态库已经完成。
2. 下面要做的是写一个测试程序来调用刚才生成的testDll.dll文件。
新建一个名为callDll的Console appliation项目,修改main.c代码如下:
#include
<
stdio.h
>
#include < stdlib.h >
#include < windows.h >
typedef int ( * lpAddFun)( int , int ); // 宏定义函数指针类型
int main()
{
HINSTANCE hDll = NULL; //DLL句柄
lpAddFun addFun = NULL; //函数指针
int result = 0;
hDll = LoadLibrary("testDll_r1.dll"); /*加载 testdll.dll*/
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "addxy");
if (addFun != NULL)
{
result = addFun(654, 212); /* 654 + 212*/
printf("%d", result);
}
FreeLibrary(hDll);
}
return 0;
}
#include < stdlib.h >
#include < windows.h >
typedef int ( * lpAddFun)( int , int ); // 宏定义函数指针类型
int main()
{
HINSTANCE hDll = NULL; //DLL句柄
lpAddFun addFun = NULL; //函数指针
int result = 0;
hDll = LoadLibrary("testDll_r1.dll"); /*加载 testdll.dll*/
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "addxy");
if (addFun != NULL)
{
result = addFun(654, 212); /* 654 + 212*/
printf("%d", result);
}
FreeLibrary(hDll);
}
return 0;
}