<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 45, 文章 - 6, 評論 - 4, 引用 - 0
    數據加載中……

    DllMain詳解

    DllMain詳解

    1   DLL的進入/退出函數

    1.1 DllMain簡介

    跟exe有個main或者WinMain入口函數一樣,DLL也有一個入口函數,就是DllMain。以“DllMain”為關鍵字,來看看MSDN幫助文檔怎么介紹這個函數的。

    The DllMain function is an optional method of entry into a dynamic-link library (DLL)。(簡要翻譯:對于動態鏈接庫,DllMain是一個可選的入口函數。)這句話很重要,很多初學者可能都認為一個動態鏈接庫肯定要有 DllMain函數。其實不然,像很多僅僅包含資源信息的DLL是沒有DllMain函數的。

    1.2 何時調用DllMain

           系統是在什么時候調用DllMain函數的呢?靜態鏈接時,或動態鏈接時調用LoadLibrary和FreeLibrary都會調用DllMain函數。DllMain的第三個參數fdwReason指明了系統調用Dll的原因,它可能是:

    DLL_PROCESS_ATTACH、

    DLL_PROCESS_DETACH、

    DLL_THREAD_ATTACH

    DLL_THREAD_DETACH。

    以下從這四種情況來分析系統何時調用了DllMain。            

    1.2.1 DLL_PROCESS_ATTACH

           大家都知道,一個程序要調用Dll里的函數,首先要先把DLL文件映射到進程的地址空間。要把一個DLL文件映射到進程的地址空間,有兩種方法:靜態鏈接和動態鏈接的LoadLibrary或者LoadLibraryEx。

           當一個DLL文件被映射到進程的地址空間時,系統調用該DLL的DllMain函數,傳遞的fdwReason參數為 DLL_PROCESS_ATTACH。這種調用只會發生在第一次映射時。如果同一個進程后來為已經映射進來的DLL再次調用LoadLibrary或者 LoadLibraryEx,操作系統只會增加DLL的使用次數,它不會再用DLL_PROCESS_ATTACH調用DLL的DllMain函數。不同 進程用LoadLibrary同一個DLL時,每個進程的第一次映射都會用DLL_PROCESS_ATTACH調用DLL的DllMain函數。

           可參考DllMainTest的DLL_PROCESS_ATTACH_Test函數。

    1.2.2 DLL_PROCESS_DETACH

           當DLL被從進程的地址空間解除映射時,系統調用了它的DllMain,傳遞的fdwReason值是DLL_PROCESS_DETACH。當DLL處理該值時,它應該執行進程相關的清理工作。

           那么什么時候DLL被從進程的地址空間解除映射呢?兩種情況:

           ◆FreeLibrary解除DLL映射(有幾個LoadLibrary,就要有幾個FreeLibrary

           ◆進程結束而解除DLL映射,在進程結束前還沒有解除DLL的映射,進程結束后會解除DLL映射。(如果進程的終結是因為調用了 TerminateProcess,系統就不會用DLL_PROCESS_DETACH來調用DLL的DllMain函數。這就意味著DLL在進程結束前 沒有機會執行任何清理工作。)

           注意:當用DLL_PROCESS_ATTACH調用DLL的DllMain函數時,如果返回FALSE,說明沒有初始化成功,系統仍會用DLL_PROCESS_DETACH調用DLL的DllMain函數。因此,必須確保清理那些沒有成功初始化的東西。

           可參考DllMainTest的DLL_PROCESS_DETACH_Test函數。

    1.2.3 DLL_THREAD_ATTACH

           當進程創建一線程時,系統查看當前映射到進程地址空間中的所有DLL文件映像,并用值DLL_THREAD_ATTACH調用DLL的DllMain函數。

    新創建的線程負責執行這次的DLL的DllMain函數,只有當所有的DLL都處理完這一通知后,系統才允許進程開始執行它的線程函數。

    注意跟DLL_PROCESS_ATTACH的區別,我們在前面說過,第 n(n>=2)次以后地把DLL映像文件映射到進程的地址空間時,是不再用DLL_PROCESS_ATTACH調用DllMain的。而 DLL_THREAD_ATTACH不同,進程中的每次建立線程,都會用值DLL_THREAD_ATTACH調用DllMain函數,哪怕是線程中建立 線程也一樣。

    1.2.4 DLL_THREAD_DETACH

           如果線程調用了ExitThread來結束線程(線程函數返回時,系統也會自動調用ExitThread),系統查看當前映射到進程空間中的所有DLL文 件映像,并用DLL_THREAD_DETACH來調用DllMain函數,通知所有的DLL去執行線程級的清理工作。

           注意:如果線程的結束是因為系統中的一個線程調用了TerminateThread,系統就不會用值DLL_THREAD_DETACH來調用所有DLL的DllMain函數。

    1.3 為DllMain換名

    在早期的SDK版本中,DllMain是叫做DllEntryPoint。其實有一件鮮為人 知的事:一個Dll的入口函數名是可以自己定義的。下面我將以VC++6.0為例來演示如何更改。首先要說明一點,雖然DllMain可以換成其他函數 名,但函數的參數和返回值必須和DllMain一樣。而且這個函數要為__stdcall類型(DllMain本身也是__stdcall類型)。

    打開VC++菜單Project"Settings"Link tab" Output in the Category box,如下圖,在Entry-point symbol中輸入要替換DllMain的函數名(當然這個函數名是你程序中已經實現的函數)。Entry-point symbol是干么的呢?可以以關鍵字“Entry-point symbol”搜索MSDN幫助文檔查看,搜索時,打鉤“僅搜索標題”會更快定位。

    DllMain詳解 - 生活 - 無敵

             按OK后,如果馬上編譯的話會出現如下錯誤:

    LIBCMTD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main

    Debug/Dll.dll : fatal error LNK1120: 1 unresolved externals

    打開VC++菜單Project"Settings"C/C++選項卡,如下圖,在 Project Options:末尾的地方添加”/D”(圖中藍色高亮的地方),要注意位置,我試了,要把/D放到/GZ后面也會鏈接錯誤,我也不懂為什么,^_^。按 OK,再次編譯,成功。大家可以自己測試下到底有沒有更改成功,什么,如果測試?打出調式信息啊。

    DllMain詳解 - 生活 - 無敵

    1.4 DisableThreadLibraryCalls

    看幫助就知道它是干么用的:

    The DisableThreadLibraryCalls function disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the dynamic-link library (DLL) specified by hLibModule. This can reduce the size of the working code set for some applications.

    轉自:http://blog.csdn.net/benkaoya/archive/2008/06/02/2504781.aspx

    posted on 2009-11-30 15:25 liyang 閱讀(333) 評論(0)  編輯  收藏 所屬分類: C語言


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲女初尝黑人巨高清| 69精品免费视频| 免费看无码自慰一区二区| 亚洲videos| 69成人免费视频无码专区| 久久亚洲AV成人无码| 99re免费99re在线视频手机版| 久久久久久a亚洲欧洲AV| 亚欧免费一级毛片| 亚洲综合在线成人一区| h片在线免费观看| 国产精品亚洲片夜色在线| 成人毛片免费观看视频在线| 亚洲人成色99999在线观看| 国产无遮挡裸体免费视频| 深夜福利在线免费观看| 亚洲A丁香五香天堂网| 中文无码日韩欧免费视频| 久久91亚洲人成电影网站| 午夜无码A级毛片免费视频| 亚洲嫩草影院在线观看| 成人免费视频一区| 美女扒开尿口给男人爽免费视频| 亚洲人成网站18禁止一区| 国产在线播放线91免费| 亚洲美女aⅴ久久久91| 在线jlzzjlzz免费播放| 一级视频在线免费观看| 久久夜色精品国产噜噜噜亚洲AV | 日韩免费视频一区二区| 337p日本欧洲亚洲大胆精品555588| 免费福利网站在线观看| 国产成人高清亚洲一区久久| 国产A在亚洲线播放| 无码中文在线二区免费| a级毛片免费高清视频| 亚洲综合网美国十次| 国产午夜无码视频免费网站| 久久免费美女视频| 亚洲人成网亚洲欧洲无码| 亚洲精品亚洲人成人网|