From:<<vc++ 深入详解>>
1.应用程序要访问某个DLL中的函数,那么该函数必须是已经被导出的函数。可以用vc命令行工具Dumpbin来查看,也可以用GUI工具depends来查看。
2.为了让DLL导出一些函数,需要在每一个将要被导出的函数前面添加标识符:__declspec(dllexport)
如:
__declspec(dllexport) int add(int a, int b)
{
return a+b;
}
__declspec(dllexport) int subtract(int a, int b)
{
return a+b;
}
3.DLL工程生成的2个文件.lib和.dll中,.lib文件是dll文件的引入库文件,保存了dll中导出的函数和变量的符号名。
隐式加载DLL文件:可在link选项卡下加载*.lib文件,也可用#pragma comment(lib,"***")来隐式加载该文件。
显式加载DLL文件:HMODULE LoadLibrary(LPCTSTR lpFileName);
4.在使用DLL中的函数时,需要先声明。有2种方法:extern和__declspec(dllimport)。
extern int add(int a, int b);
extern int subtract(int a, int b);
__declspec(dllimport) int add(int a ,int b);
__declspec(dllimport) int subtract(int a, int b);
Win32 Dll完善
5.可以将
__declspec(dllimport) int add(int a ,int b);
__declspec(dllimport) int subtract(int a, int b);
语句定义在dll工程的头文件中,在调用DLL的工程中包含该头文件即可。
6.实现在DLL客户端和DLL程序自身来使用,改造后的DLL.H文件如下:
#ifdef DLL1_API
#else
#define DLL1_API __declspec(dllimport)
#endif
DLL1_API int add(int a, int b);
DLL1_API int subtract(int a, int b);
在dll程序自身的源文件中编写如下内容
#define DLL1_API __declspec(dllexport)
#include "dll.h"
int add(int a ,int b)
{return a+b;}
int subtract(int a, int b)
{return a-b;}
解决名字改编问题
在生成DLL时,编译器会对导出的函数进行名字改编,不同的编译器改编规则不一样。为了能够调用不同语言编写的DLL,可以让导出函数名不改编。为了实现这一目的,在定义导出函数时,需要加上限定符:
extern “C"。
如#define DLL1_API extern "C" __declspec(dllimport)
extern "C" 可以解决C++和C语言之间相互调用时函数命名的问题。但是这种方法有一个缺陷就是不能用于导出一个类的成员函数,只能用于导出全局函数这种情况。
而如果导出函数的调用约定发生了改变,则extern ”C“限定符就不起作用了,C语言和DELPHI使用的调用约定是不一样的,后者使用pascal调用约定,也即标准调用约定__stdcall,即WINAPI。这时C和delphi之间需使用DEF模块定义文件解决名字改编问题
LIBRARY Dll2
EXPORTS
add
subtract