dll知识
来源:互联网 发布:linux 命令返回结果 编辑:程序博客网 时间:2024/05/04 15:06
C++动态链接库(dll)(二)
C++学习2010-05-11 16:26:03 阅读103评论0 字号:大中小 订阅
(一)名字改编问题:
C++编译器生成DLL时,会对导出的函数进行名字改编,由于编译器采用的改编原则是不一样的,因此改编后的名字也是不一样的。这样如果利用不同的编译器分别生成DLL和访问该DLL的客户端程序的话,后者在访问该DLL的导出函数时会出现问题。
当希望动态链接库文件在编译时,导出函数的名称不要发生改变,可在定义导出函数时,需要加上限定符:extern “C”。还是以Dll1和DllTest为例。
Dll1.h如下:
#ifdef DLL1_API
#else
#define DLL1_API extern "C" _declspec(dllimport)
#endif
DLL1_API int add(int a,int b);
DLL1_API int subtract(int a,int b);
Dll1.cpp如下:
#define DLL1_API extern "C" _declspec(dllexport)
#include"Dll1.h"
#include<Windows.h>
#include<stdio.h>
int add(int a,int b)
{
return a+b;
}
int subtract(int a,int b)
{
return a-b;
}
则利用dumpbin命令查看可看到导出的函数名为add和subtract,但这种方法有一个缺陷,就是不能用于导出一个类的成员函数,只能用于导出全局函数这种情况,所以Dll1里的类定义被注释掉了。另外,如果导出函数的调用约定发生了改变,这种方法也会失效的。一种万全的方法是定义一个模块定义文件(.def)文件,在项目——>添加新项中选择添加def文件即可,然后在其中输入:
LIBRARY DLL1
EXPORTS
add
subtract
当链接器分析def文件时发现EXPORTS语句下有add和subtract这两个符号名,并且和源文件中定义的add和subtract函数的名字是一样的时候,它就会以add和subtract这两个符号名导出相应的函数。如果要导出的符号名和源文件定义的函数名不一样,则可以按照下述语法导出:
entryname=internalname
entryname是要导出的符号名,internalname是DLL中将要导出的函数的名字。
(二)显式加载DLL:
显式加载DLL,也即动态加载DLL时,客户端程序不再需要包含导出函数声明的头文件(.h)和引入库文件(.lib),只需要.dll文件即可。显式加载最主要有两个函数,分别是LoadLibrary和GetProcAddress,声明如下:
HMODULE LoadLibrary(LPCTSTR lpFileName);
FARPROC GetProcAddress(HMODULE hModule,LPCTSTR lpProcName);
LoadLibrary可以加载DLL,也可以加载可执行模块(.exe),返回的是加载的模块的句柄,注意HMODULE和HINSTANCE是可以通用的。
GetProcAddress中,hModule是动态链接库模块的句柄,lpProcName是要导出的函数的名字,当然也可以是序号,序号则需要用到MAKEINTRESOURCE宏,该宏会把指定的函数序号转换为相应的函数名字字符串,如上例,MAKEINTRESOURCE(1)表示函数add,要查看函数的序号可以用dumpbin命令中的exports选项查看。下面给出一个调用的例子:
{
HINSTANCE hInst;
hInst=LoadLibrary(_T("Dll3.dll")); //动态加载DLL
typedef int (*ADDPROC)(int a,int b); //定义函数指针类型
ADDPROC Add=(ADDPROC)GetProcAddress(hInst,”add”);
//也可以用(ADDPROC Add=(ADDPROC)GetProcAddress(hInst,(LPCSTR)MAKEINTRESOURCE(1));)
if(!Add)
{
MessageBox(_T("获取函数地址失败!"));
return;
}
CString str;
str.Format(_T("5+3=%d"),Add(5,3));
MessageBox(str);
FreeLibrary(hInst);
}
上述代码中定义了一个函数指针类型:ADDPROC,用来接收通过GetProcAddress返回的函数地址,当然定义要根据导出的函数进行定义,由于GetProcAddress返回的是FARPROC类型,需要强制转换。另外注意的是,当不再需要访问该DLL时,必须调用FreeLibrary函数释放对该DLL的引用。一般地,使用动态加载效率更高。
以上是学习孙鑫老师的《VC++深入详解》相关内容后的笔记。接下来打算解决的问题是dll的搜索顺序和字符的区分和转换。
- DLL 知识
- dll知识
- dll的一些知识
- DLL相关知识
- DLL相关知识总结
- DLL知识小结
- Dll知识小总结
- Dll 入门知识
- dll相关知识
- dll相关知识备忘
- DLL的入门知识
- 有关dll的一些知识
- DLL的一些背景知识
- MFC DLL的一些知识
- Delphi下DLL编程知识
- .lib和.dll的知识
- 关于dll的一些知识
- dll 学习相关知识总结
- 关注中国移动互联网市场:海外移动互联企业图谋中国 喜大市场忧大差异
- Linux内核SPI子系统架构分析
- CString 转为 std::string
- RHEL6.0上各种邮件服务器的搭建
- Linux下nginx支持.htaccess文件实现伪静态的方法!
- dll知识
- QQPHP笔试
- UDP与TCP的差异
- opengl绝无仅有的漫游程序qt专用
- 文件遍历
- HDU 1079 Calendar Game (博弈)
- 上班族必备的电脑小技巧
- windows-win7桌面图标变了样子能运行并非中病毒!
- myeclipse安装svn插件的多种方式