博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于dllmain以及dll函数调用的理解。
阅读量:6967 次
发布时间:2019-06-27

本文共 2213 字,大约阅读时间需要 7 分钟。

关于dllmain的百度百科的学习。

 

一个程序要调用dll里的函数,首先要将此dll文件映射到程序进程的地址空间(从磁盘文件映射到内存地址空间 ,PE文件装载器读取),要把dll文件映射到程序进程的地址空间有两种方法:静态链接和动态链接的LoadLibrary或者LoadLibraryEx

程序要调用DLL里的函数,使用Loadliabrary时,会调用DLLMain函数。

当一个dll被映射到进程的地址空间时,系统会调用该dll的dllmain 函数,传递dwReason参数为DLL_PROCESS_ATTATCH,这种调用只会发生在第一次调用,如果同一进程为后来已经映射进来的dll再次调用LoadLibrary或者LoadLibraryEx,操作系统只会增加dll的调用次数,他不会再用DLL_PROCESS_ATTATCH调用DLL的DLLMAIN。

 *****************************************************************

我们知道,在MFC应用程序中CWinApp取代了SDK程序中WinMain的地位,SDK程序WinMain所完成的工作由CWinApp的三个函数完成:

virtual BOOL InitApplication( );

virtual BOOL InitInstance( );
virtual BOOL Run( ); //传说中MFC程序的“活水源头”

另外,MFC规则DLL与MFC 应用程序中一样,需要将所有 DLL中元素的初始化放到InitInstance 成员函数中。

可以试验一下dllmain的一次调用。增加InitInstance函数,如下:

BOOL CRegularDllApp::InitInstance()

{
// TODO: Add your specialized code here and/or call the base class
CString dxs;
dxs="dxsaslfll";
AfxMessageBox(dxs);
return CWinApp::InitInstance();
}

在应用程序中调用时,如下函数,会首次调用InitInstance函数的AfxMessageBox dxsaslfll,再次点击按钮时候不在调用InitInstance.

 

void CRegularDllCallDlg::OnCalldllButton()

{
typedef void (*lpFun)(void);
HINSTANCE hDll; //DLL句柄
hDll = LoadLibrary("RegularDll.dll");
if (NULL==hDll)
{
MessageBox("DLL加载失败");
}

//lpFun addFun; //函数指针

lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg");//指的是ShowDlg的返回为void 参数为void
if (NULL==pShowDlg)
{
MessageBox("DLL中函数寻找失败");
}
pShowDlg();

/* AfxMessageBox("dd");*/

}

 

 

 *****************************************************************

我用一个my.dll,自动联接av.dll,我用LoadLibrary("my.dll"),GetLastError返回

”指定的模块找不到“,再用LoadLibraryEx("my.dll",NULL,DONT_RESOLVE_DLL_REFERENCES)就ok.

(附:1. DONT_RESOLVE_DLL_REFERENCES,DONT_RESOLVE_DLL_REFERENCES标志用于告诉系统将DLL映射到调用进程的地址空间中。通常情况下,当DLL被映射到进程的地址空间中时,系统要调用 D L L中的一个特殊函数,即 DllMain。该函数用于对DLL进行初始化。 DONT_RESOLVE_DLL_REFERENCE S标志使系统不必调用Dll Main函数就能映射文件映像。

D L L能够输入另一个D L L中包含的函数。当系统将一个 D L L映射到进程的地址空间
中时,它也要查看该DLL是否需要其他的DLL,并且自动加载这些DLL。当DONT_RESOLVE _DLL_REFERENCES标志被设定时,系统并不自动将其他的DLL加载到进程的地址空间中。)

DLL难道是av.dll找不到,但av.dll是我在编译my.dll时加av.lib自动联上的,请问有什么直接的办法来检测自动联接的av.dll是否在LoadLibrary("my.dll")时是错误之根源??

 

LoadLibraryEx可设置 DONT_RESOLVE_DLL_REFERENCE使得系统不必调用dllmain函数就能映射dll文件。 DONT_RESOLVE_DLL_REFERENCES:不对DLL进行初始化,仅用于NT。

 

转载于:https://www.cnblogs.com/daziduan/p/3530601.html

你可能感兴趣的文章
Android平台<软硬整合实践技术>_答问集
查看>>
云计算数据中心:想好了再做
查看>>
将一些类型设计成集合模式
查看>>
吉林艺术学院监考人员被指为考生改画 学校回应
查看>>
为什么程序员应该有一台 Mac 个人电脑
查看>>
iOS 开发中 runtime 常用的几种方法
查看>>
JS执行机制(浏览器事件环 vs Node事件环)
查看>>
树形数据结构总结一(堆,Trie,并查集)
查看>>
企业上云的四个阶段
查看>>
九、 一个简单的播放器(各自同步)
查看>>
一步一图,带你了解分布式架构的前世今生!
查看>>
转行程序员深漂的这三年 #3
查看>>
[转载]责任链模式
查看>>
揭秘!双11万亿流量下的分布式缓存系统 Tair
查看>>
[译] iPhone X 网页设计
查看>>
webpack入门及踩坑应对指南
查看>>
对于数据库优化的理解
查看>>
python学习三:列表、元组、字典、集合
查看>>
Netty 框架总结「ChannelHandler 及 EventLoop」
查看>>
Linux 下启动 Tomcat 抛出Can't connect to X11 window server 问题的解决方法
查看>>