动态(静态)加载DLL注意
动态加载DLL的方法与注意的问题
动态加载DLL的方法:
1. 生成dll过程:把生成的.DLL文件复制到测试工程DLLTest目录下。这里假设该.DLL文件为add.dll,主要代码是:
// .h中声明
Extern “C” _declspec(dllexport) int add(int x, int y)
// .cpp 中实现
extern "C" int add(int x, int y)
{
return x + y;
}
2.使用1生成的dll:在DLLTest工程中添加DllTest.cpp文件.
首先使用LoadLibrary("add.dll")加载add.dll文件:
HMODULE hmod = LoadLibrary("add.dll");
然后定义一个函数指针的类型:
typedef int (*AddAddr)(int x, int y);
注意,这里的参数与返回类型务必与add.dll文件中函数add的声明一样。
接着:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "add");
如果Add值为空,则获取函数的地址失败!
if(!Add)
{
printf("获取函数地址失败!");
return;
}
最后,可以测试一下:
printf("test add(): 1+2=%d", add(1,2));
运行结果一看,会出现“获取函数地址失败!”。为什么会这样?
打开命令行,用cd命令到add.dll工程目录的debug目录下,然后使用命令:
dumpbin -exports add.dll
则会看到add.dll文件中的add函数的名称为“?add@@YAHHH@Z”,而不是函数名add,这是C++编译器的命名改编机制。 修改原来的代码:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "?add@@YAHHH@Z");
这时运行就成功了。但如果按这样去动态加载DLL,那每次获取函数地址都要使用dumpbin命令去获取,则会很麻烦。
那怎样可以直接使用add而不是 ?add@@YAHHH@Z这个长长的字符串呢,修改add.dll的add函数,在函数前加上extern "C",再编译add.dll文件所在的工程,复制新生成的add.dll覆盖DLLTest工程目录下的add.dll,原来的代码获取函数地址时使用add,结果运行就成功了。
而再使用dumpbin -exports add.dll命令,显示add.dll的中的add函数的名称变成了add.
静态加载
隐式链接会把DLL中所有标志为_declspec(dllexport)的函数都加载,如果有多个DLL加载时,可能会影响到程序执行的效率。而用动态加载DLL的方式则可以根据需要去加载用到的函数。
// .h中
#ifdef COUNTER_EXPORTS
#define COUNTER_API _declspec(dllexport)
#else
#define COUNTER_API _declspec(dllimport)
#endif
// 声明要导出的函数
int COUNTER_API WINAPI _IncCounter();
----------------------------------------------------------------------------------------------------------
// .cpp中
int WINAPI _IncCounter()
{
dwCounter ++;
_CheckCounter(dwCounter);
return dwCounter;
}
----------------------------------------------------------------------------------------------------------
// .def
EXPORTS
_IncCounter
----------------------------------------------------------------------------------------------------------
#include "Counter.h"
#pragma comment(lib, "Counter.lib")
----------------------------------------------------------------------------------------------------------
动态链接库中共享
// 共享数据段
#pragma data_seg("mahongmou")
HWND g_hWndCaller = NULL; // 保存主窗口句柄
HHOOK g_hHook = NULL; // 保存钩子句柄
#pragma data_seg()
-------------------------------------
SECTIONS
mahongmou Read Write Shared
转载于:https://www.cnblogs.com/xiaojinma/archive/2012/12/06/2805577.html
动态(静态)加载DLL注意相关推荐
- VC静态加载DLL和动态加载DLL
VC静态加载DLL和动态加载DLL 1. 静态加载DLL 如果你有a.dll和a.lib,两个文件都有的话可以用静态加载的方式: message函数的声明你应该知道吧,把它的声明和下面的语句写到一个头 ...
- PySide2动态/静态加载UI及程序发布
Python目前已经是一个"家喻户晓"的名词了,她可能用在很多行业领域,最牛逼的人工智能(AI).大数据(big data).今天要介绍的是Python图形化界面实现(GUI),记 ...
- 静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件。
静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件. 一. 静态链接库(LIB,也简称"静态库")与动态链接库(DLL,也简称"动态库 ...
- C#动态加载DLL(转)
利用反射进行动态加载和调用. Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载 加载dll后,需要使用dll中某类. Type type=as ...
- 动态加载vs静态加载
动态加载: 1:灵活,可以在需要的时候用LoadLibrary进行加载,在不需要的时候用FreeLibrary进行卸载,这样可以不必占用内存. 2:可以在没有dll时候发现,而不致程序报错. 3:加载 ...
- c#实现动态加载Dll
原理如下: 1.利用反射进行动态加载和调用. Assembly assembly=Assembly.LoadFrom(DllPath); //利用dll的路径加载,同时将此程序集所依赖的程序集 ...
- 软件库Library之静态库\动态库和静态加载\动态加载
软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...
- Unity3D的坑系列:动态加载dll
Unity3D的坑系列:动态加载dll 我现在参与的项目是做MMO手游,目标平台是Android和iOS,iOS平台不能动态加载dll(什么原因找乔布斯去),可以直接忽略,而在Android平台是可以 ...
- 【原】 动态加载dll
动态调用动态库步骤: 1.创建一个函数指针,其指针数据类型要与调用的DLL引出函数相吻合. 2.通过Win32 API函数LoadLibrary()显式的调用DLL,此函数返回DLL的实例句柄. 3. ...
最新文章
- 刚过国家线计算机考研报哪个好,考研估分刚过了去年国家线,今年上岸还有希望吗?有!...
- 中国Nature第一人,居然是清朝的他
- iOS手势操作简介(六)
- C# 窗口大小及屏幕分辨率操作
- Tinker的简单接入
- 利用iframe来做无刷新上传
- 「零基础从零开始写VO视觉里程计」如何求解线性方程 Hdx=b?(7-)
- 30天扣篮训练计划_高强度减脂训练计划,每天练30分钟,坚持一个月,减掉多余的脂肪...
- 大众帕萨特卡尔福安卓智能车载导航评测
- 项目管理四要素是什么?
- 程序人生-我已经努力了七年!!!
- 搭建gos_如何将记录器注入gos http处理程序
- Laravel Eloquent 关联
- 深井泵房无人值守系统 泵站无人值守平台 智慧水务
- 哈工大计算机学院张宏莉,计算机科学与技术学科博士研究生培养方案2014-哈工大计算机学院.DOC...
- 第130章 SQL函数 SQRT
- 六石管理学:突然看到两个男同事聊天,预判离职
- 九章量子计算机地位,“九章”量子计算机这么牛,到底有什么用?|【经纬低调分享】...
- php printer_open 用法_php – 调用未定义的函数printer_open()
- saveOrUpdate Transaction silently rolled back because it has been marked as rollback-only
热门文章
- python语法31[变量的作用域+global]
- java基础------多线程(转)
- 粒度计算机英语,An Overview of Granular Computing粒度计算研究综述
- 在DOS下如何加载SATA光驱驱动
- GitHub优秀移动开源项目大集合
- Go语言中Tcp协议粘包问题处理
- 页游中的十大经典游戏题材
- 计算机绘图自考知识点,全国自考机械制图一试题2004.04
- mysql 分表分库mycat_Mysql数据库之如何Mycat分表分库?
- 【java奇思妙想】关于JavaScript实现全选,全不选以及反选功能的示例