本文共 2251 字,大约阅读时间需要 7 分钟。
1。用于静态链接: 给系统调用静态链接的时候,知道导出函数的地址在哪里dll文件名是什么,静态链接编译的时候, 由编译器把这些信息加入到exe文件中 静态调用方式的顺利进行需要完成两个动作: (1)告诉编译器与DLL相对应的.lib文件所在的路径及文件名,#pragma comment(lib,"dllTest.lib")就是起这个作用。 程序员在建立一个DLL文件时,连接器会自动为其生成一个对应的.lib文件,该文件包含了DLL 导出函数的符号名及序号(并不含有实际的代码)。在应用程序里,.lib文件将作为DLL的替代文件参与编译。 (2)声明导入函数,extern "C" __declspec(dllimport) add(int x,int y)语句中的__declspec(dllimport)发挥这个作用。 静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址。这是因为,当程序员通过静态链接方式编译生成应用程序时,应用 程序中调用的与.lib文件中导出符号相匹配的函数符号将进入到生成的EXE 文件中,.lib文件中所包含的与之对应的DLL文件的文件名也被编译器存储在 EXE文件内部。当应用程序运行过程中需要加载DLL文件时,Windows将根据这些信息发现并加载DLL,然后通过符号名实现对DLL 函数的动态链接。这样,EXE将能直接通过函数名调用DLL的输出函数,就象调用程序内部的其他函数一样。 2。用于导出dll中的全局变量本身而不是dll中全局变量的地址(指针变量一个) DLL定义的全局变量可以被调用进程访问;DLL也可以访问调用进程的全局数据,我们来看看在应用工程中引用DLL中变量的例子/* 文件名:lib.h */
#ifndef LIB_H#define LIB_Hextern int dllGlobalVar;#endif/* 文件名:lib.cpp */#include "lib.h"#include <windows.h>int dllGlobalVar;BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch (ul_reason_for_call){ case DLL_PROCESS_ATTACH:dllGlobalVar = 100; //在dll被加载时,赋全局变量为100break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;};文件名:lib.def;在DLL中导出变量LIBRARY "dllTest"EXPORTSdllGlobalVar CONSTANT;或dllGlobalVar DATAGetGlobalVar 从lib.h和lib.cpp中可以看出,全局变量在DLL中的定义和使用方法与一般的程序设计是一样的。若要导出某全局变量,我们需要在.def文件的EXPORTS后添加:变量名 CONSTANT //过时的方法
或变量名 DATA //VC++提示的新方法
在主函数中引用DLL中定义的全局变量:#include <stdio.h>
#pragma comment(lib,"dllTest.lib")extern int dllGlobalVar;int main(int argc, char *argv[]){ printf("%d ", *(int*)dllGlobalVar);*(int*)dllGlobalVar = 1;printf("%d ", *(int*)dllGlobalVar);return 0;} 特别要注意的是用extern int dllGlobalVar声明所导入的并不是DLL中全局变量本身,而是其地址,应用程序必须通过强制指针转换来使用DLL中的全局变量。这一点,从* (int*)dllGlobalVar可以看出。因此在采用这种方式引用DLL全局变量时,千万不要进行这样的赋值操作:dllGlobalVar = 1;
其结果是dllGlobalVar指针的内容发生变化,程序中以后再也引用不到DLL中的全局变量了。 在应用工程中引用DLL中全局变量的一个更好方法是:#include <stdio.h>
#pragma comment(lib,"dllTest.lib")extern int _declspec(dllimport) dllGlobalVar; //用_declspec(dllimport)导入int main(int argc, char *argv[]){ printf("%d ", dllGlobalVar);dllGlobalVar = 1; //这里就可以直接使用, 无须进行强制指针转换printf("%d ", dllGlobalVar);return 0;} 通过_declspec(dllimport)方式导入的就是DLL中全局变量本身而不再是其地址了,笔者建议在一切可能的情况下都使用这种方式。转载地址:http://tedqi.baihongyu.com/