您的位置:首页 > 其它

windows下 DLL 的学习

2013-10-13 11:34 295 查看
windwos下的 DLL 有copy on write (写入拷贝机制)

如果调用G e t M o d u l e H a n d l e函数,线程就能够确定D L L是否已经被映射到进程的地址空间

HINSTANCE hInstance=GetMoudleHandle("MyLib");

if(!hInstance )

{

HINSTANCE hInstanceDll= LoadLibrary("MyLib.dll");

}

例如,只有当MyLib.dll尚未被映射到进程的地址空间中时,下面这个代码才能加载该文件:

通过GetProcAddress 函数来获取动态链接库中的函数地址

PROCFUN myFun= GetProcAddress(hInstanceDll,"MyFunAdd");

myFun(1,2);

顺序调用DLL

系统是顺序调用D L L的D l l M a i n函数的。为了理解这样做的意义,可以考虑下面这样一个环境。假设一个进程有两个线程,线程A和线程B。该进程还有一个D L L,称为S o m e D L L . d l l,它被映射到了它的地址空间中。两个线程都准备调用C r e a t e T h r e a d函数,以便再创建两个线程,即线程C和线程D。

当线程A调用C r e a t e T h r e a d来创建线程C时,系统调用带有D L L _ T H R E A D _ AT TA C H值的S o m e D L L . d l l的D l l M a i n函数。当线程C执行D l l M a i n函数中的代码时,线程B调用C r e a t e T h r e a d函数来创建线程D。这时系统必须再次调用带有D
L L _ T H R E A D _ AT TA C H值的D l l M a i n函数,这次是让线程D 执行代码。但是,系统是顺序调用D l l M a i n函数的,因此系统会暂停线程D的运行,直到线程C完成对D l l M a i n函数中的代码的处理并且返回为止。

当线程C完成D l l M a i n的处理后,它就开始执行它的线程函数。这时系统唤醒线程D,让它处理D l l M a i n中的代码。当它返回时,线程D开始处理它的线程函数。

通常情况下,根本不会考虑到D l l M a i n的这个顺序操作特性。我曾经遇到过一个人,他的代码中有一个D l l M a i n顺序操作带来的错误。他创建的代码类似下面的样子:

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD fdwReason, PVOID fImpLoad)
{
HANDLE hThread;
DWORD dwThreadId;

switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
// The DLL is being mapped into the process's address space.

// Create a thread to do some stuff.
hThread = CreateThread(NULL, 0, SomeFunction, NULL,
0, &dwThreadId);

// Suspend our thread until the new thread terminates.
WaitForSingleObject(hThread, INFINITE);

// We no longer need access to the new thread.
CloseHandle(hThread);
break;

case DLL_THREAD_ATTACH:
// A thread is being created.
break;

case DLL_THREAD_DETACH:
// A thread is exiting cleanly.
break;

case DLL_PROCESS_DETACH:
// The DLL is being unmapped from the process's address space.
break;
}
return(TRUE);
}


你能够看出这个问题吗?当D l l M a i n收到D L L _ P R O C E S S _ AT TA C H 通知时, 一个新线程就创建了。系统必须用D L L _ T H R E A D _ AT TA C H的值再次调用D l l M a i n函数。但是,新线程被暂停运行,因为导致D L L _ P R O C E S S _ AT TA C H被发送给D l l
M a i n函数的线程尚未完成处理操作。问题是调用Wa i t F o r S i n g l e O b j e c t函数而产生的。这个函数使当前正在运行的线程暂停运行,直到新线程终止运行。但是新线程从未得到机会运行,更不要说终止运行,因为它处于暂停状态,等待当前线程退出D l l M a i n函数。这里我们得到的是个死锁条件。两个线程将永远处于暂停状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: