如果之前没有调用过LoadLibrary(Ex)或者LoadLibrary(Ex)和FreeLibrary都是配对使用的,那么OS在调用LoadLibrary(Ex)的当前线程中调用入口点函数。
若OS找不到DLL或入口函数返回 FALSE,LoadLibrary(Ex)返回NULL;否则返回DLL模块句柄,此句柄可用于GetProcAddress, FreeLibrary, FreeLibraryAndExitThread。GetModuleHandle 针对已装入的DLL获取DLL句柄,GetModuleFileName则从句柄获得文件绝对全名。
运行时动态链接允许APP灵活处理DLL文件找不到的情况,例如尝试一下其它的文件名,或报错,或请用户指定正确的DLL文件路径。
注意:动态链接的DLL只能看到那些它装入(即LoadLibrary调用)之后的线程,因此对于要针对进程中所有线程进行操作的应用,需要参考MSDN的Using Thread Local Storage in a Dynamic-Link Library。
下面的代码演示了生成时附加lib库和运行时直接装入的区别。
#include <stdio.h>
#include <windows.h>
typedef int (*MYPROC)(LPTSTR);
VOID main(VOID)
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("myputs"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, TEXT("myPuts"));
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (TEXT("Message via DLL function/n"));
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message via alternative method/n");
}