DLL 延时加载
来源:互联网 发布:阿里云服务器申请退款 编辑:程序博客网 时间:2024/06/16 09:41
1. exe加载多个dll时,初始化可能会比较慢
2. exe加载老版本dll时,如果没有相应的导出函数,exe可以做相应处理后继续执行。
局限性
1)导出全局变量不能延迟。
2)kernel32.dll 不能延迟, LoadLibrary and GetProcAddress
3) 不能在dllmain中调用延迟加载的函数。
onedll.dll project
//onedll.h
#ifdef ONEDLL_EXPORTS
#define ONEDLL_API __declspec(dllexport)
#else
#define ONEDLL_API __declspec(dllimport)
#endif
extern "C" ONEDLL_API int fnLib(void);
extern "C" ONEDLL_API int fnLib2(void);
//onedll.cpp
#include "onedll.h"
ONEDLL_API int fnLib(void)
{
return 42111;
}
ONEDLL_API int fnLib2(void)
{
return 42222;
}
oneexe.exe project
//oneexe.cpp
#include <Windowsx.h>
#include <tchar.h>
#include <StrSafe.h>
#include <Windows.h>
#include <iostream>
#include <Delayimp.h> // For error handling & advanced features
#include "..\onedll.h"
#pragma comment(lib, "onedll.lib")
#pragma comment(lib, "Delayimp.lib")
// Note: it is not possible to use #pragma comment(linker, "")
// for /DELAYLOAD and /DELAY
// The name of the Delay-Load module (only used by this sample app)
wchar_t g_szDelayLoadModuleName[] = L"onedll";
// Forward function prototype
LONG WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pep);
///////////////////////////////////////////////////////////////////////////////
void IsModuleLoaded(PCTSTR pszModuleName) {
HMODULE hmod = GetModuleHandle(pszModuleName);
wchar_t sz[100];
StringCchPrintfW(sz, _countof(sz), L"Module \"%s\" is %sloaded.",
pszModuleName, (hmod == NULL) ? L"not " : L"");
std::wcout << sz << std::endl;
}
//int WINAPI _tmain(HINSTANCE hInstExe, HINSTANCE, PTSTR pszCmdLine, int)
int _tmain(int argc, _TCHAR* argv[])
{
// Wrap all calls to delay-load DLL functions inside SEH
__try {
int x = 0;
// If you're in the debugger, try the new Debug.Modules menu item to
// see that the DLL is not loaded prior to executing the line below
IsModuleLoaded(g_szDelayLoadModuleName);
x = fnLib(); // Attempt to call delay-load function
// Use Debug.Modules to see that the DLL is now loaded
IsModuleLoaded(g_szDelayLoadModuleName);
x = fnLib2(); // Attempt to call delay-load function
// Unload the delay-loaded DLL
// NOTE: Name must exactly match /DelayLoad:(DllName)
PCSTR pszDll = "onedll.dll";
BOOL bRet = __FUnloadDelayLoadedDLL2(pszDll); // link -> advanced -> Unload delay loaded DLL:yes
// Use Debug.Modules to see that the DLL is now unloaded
IsModuleLoaded(g_szDelayLoadModuleName);
x = fnLib(); // Attempt to call delay-load function
// Use Debug.Modules to see that the DLL is loaded again
IsModuleLoaded(g_szDelayLoadModuleName);
}
__except (DelayLoadDllExceptionFilter(GetExceptionInformation())) {
// Nothing to do in here, thread continues to run normally
}
// More code can go here...
return(0);
}
///////////////////////////////////////////////////////////////////////////////
LONG WINAPI DelayLoadDllExceptionFilter(PEXCEPTION_POINTERS pep) {
// Assume we recognize this exception
LONG lDisposition = EXCEPTION_EXECUTE_HANDLER;
// If this is a Delay-load problem, ExceptionInformation[0] points
// to a DelayLoadInfo structure that has detailed error info
PDelayLoadInfo pdli =
PDelayLoadInfo(pep->ExceptionRecord->ExceptionInformation[0]);
// Create a buffer where we construct error messages
char sz[500] = { 0 };
switch (pep->ExceptionRecord->ExceptionCode) {
case VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND):
// The DLL module was not found at runtime
StringCchPrintfA(sz, _countof(sz), "Dll not found: %s", pdli->szDll);
break;
case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
// The DLL module was found, but it doesn't contain the function
if (pdli->dlp.fImportByName) {
StringCchPrintfA(sz, _countof(sz), "Function %s was not found in %s",
pdli->dlp.szProcName, pdli->szDll);
} else {
StringCchPrintfA(sz, _countof(sz), "Function ordinal %d was not found in %s",
pdli->dlp.dwOrdinal, pdli->szDll);
}
break;
default:
// We don't recognize this exception
lDisposition = EXCEPTION_CONTINUE_SEARCH;
break;
}
if (lDisposition == EXCEPTION_EXECUTE_HANDLER) {
// We recognized this error and constructed a message, show it
//chMB(sz);
std::wcout << sz << std::endl;
}
return(lDisposition);
}
// Skeleton DliHook function that does nothing interesting
FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli) {
FARPROC fp = NULL; // Default return value
// NOTE: The members of the DelayLoadInfo structure pointed
// to by pdli shows the results of progress made so far.
switch (dliNotify) {
case dliStartProcessing:
// Called when __delayLoadHelper2 attempts to find a DLL/function
// Return 0 to have normal behavior or nonzero to override
// everything (you will still get dliNoteEndProcessing)
break;
case dliNotePreLoadLibrary:
// Called just before LoadLibrary
// Return NULL to have __delayLoadHelper2 call LoadLibary
// or you can call LoadLibrary yourself and return the HMODULE
fp = (FARPROC) (HMODULE) NULL;
break;
case dliFailLoadLib:
// Called if LoadLibrary fails
// Again, you can call LoadLibary yourself here and return an HMODULE
// If you return NULL, __delayLoadHelper2 raises the
// ERROR_MOD_NOT_FOUND exception
fp = (FARPROC) (HMODULE) NULL;
break;
case dliNotePreGetProcAddress:
// Called just before GetProcAddress
// Return NULL to have __delayLoadHelper2 call GetProcAddress,
// or you can call GetProcAddress yourself and return the address
fp = (FARPROC) NULL;
break;
case dliFailGetProc:
// Called if GetProcAddress fails
// You can call GetProcAddress yourself here and return an address
// If you return NULL, __delayLoadHelper2 raises the
// ERROR_PROC_NOT_FOUND exception
fp = (FARPROC) NULL;
break;
case dliNoteEndProcessing:
// A simple notification that __delayLoadHelper2 is done
// You can examine the members of the DelayLoadInfo structure
// pointed to by pdli and raise an exception if you desire
break;
}
return(fp);
}
// Tell __delayLoadHelper2 to call my hook function
PfnDliHook __pfnDliNotifyHook2 = DliHook;
PfnDliHook __pfnDliFailureHook2 = DliHook;
//note:
生成exe后,可以rename onedll.dll 名字,或者 delete 某个导出函数 测试, dependency walker 查看延迟加载的dll图标
1.一个dll中申请、释放内存
2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 可修改加载程序的搜索顺序
3. 隐式加载,可执行程序包含导出dll工程的头文件,其__declspec(dllimport) 比我们不include头文件而直接用extern 效果高
HMODULE WINAPI GetModuleHandle(__in_opt LPCTSTR lpModuleName);
传NULL,返回可执行文件的句柄,传DLL,返回dll实例句柄
DWORD WINAPI GetModuleFileName(__in_opt HMODULE hModule, __out LPTSTR lpFilename, __in DWORD nSize);
传NULL,返回可执行文件的名字,传DLL,返回dll名字
DllMain的序列货调用,系统保证一个线程执行完DllMain才会让另一个线程执行
_DllMainCRTStartup -> __DllMainCRTStartup --> _CRT_INIT, DllMain
_DllMainCRTStartup -> __DllMainCRTStartup --> DllMain, _CRT_INIT
如果用户不添加DllMain函数,将调用C/C++运行库提供的下面函数
BOOL WINAPI DllMain(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
#if defined (CRTDLL)
if ( dwReason == DLL_PROCESS_ATTACH && ! _pRawDllMain )
DisableThreadLibraryCalls(hDllHandle);
#endif /* defined (CRTDLL) */
return TRUE ;
}
- DLL 延时加载
- Windows 核心编程之Dll 延时加载
- 延时加载
- 延时加载
- 延时加载 懒加载
- 延时加载|懒加载
- Hibernate延时加载:属性延时加载与关系延时加载
- Hibernate延时加载
- Hibernate延时加载
- JPA延时加载
- Flex延时加载
- hibernate中的延时加载
- 页面数据延时加载
- Hibernate延时加载
- ibatis_延时加载
- 图片延时加载
- iOS延时加载图片
- hibernate延时加载
- HDFS体系结构简介
- UVa 10452 - Marcus
- js里常见问题
- Uva 11183 Teen Girl Squad(最小树形图 模板)
- [Cogs]-693-Antiprime数
- DLL 延时加载
- ubuntu 14.10 (64位)下载amd显卡,实现双显卡切换
- JAVA中JVM的GC日志解析
- struts2 所有常量配置详解
- Dynamics CRM 2013 SP1 升级到Dynamics CRM 2015
- slave have equal MySQL server UUIDs
- hdoj 1239 Calling Extraterrestrial Intelligence Again
- Leetcode之Palindrome Number
- poj 1502 MPI Maelstrom Dijkstra算法的简单运用 ,呵呵,,我估计有很多人都没看懂什么意思,我也看了很久