• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Windows在加載DLL的時候,需要一個入口函數,就如同控制臺或DOS程序需要main函數、WIN32程序需要WinMain函數一樣。在前面的例子中,DLL并沒有提供DllMain函數,應用工程也能成功引用DLL,這是因為Windows在找不到DllMain的時候,系統會從其它運行庫中引入一個不做任何操作的缺省DllMain函數版本,并不意味著DLL可以放棄DllMain函數。

              根據編寫規范,Windows必須查找并執行DLL里的DllMain函數作為加載DLL的依據,它使得DLL得以保留在內存里。這個函數并不屬于導出函數,而是DLL的內部函數。這意味著不能直接在應用工程中引用DllMain函數,DllMain是自動被調用的。

              我們來看一個DllMain函數的例子(單擊此處下載本工程附件)。

            BOOL APIENTRY DllMain( HANDLE hModule,

            DWORD ul_reason_for_call,

            LPVOID lpReserved

            )

            {

            switch (ul_reason_for_call)

            {

            case DLL_PROCESS_ATTACH:

            printf("\nprocess attach of dll");

            break;

            case DLL_THREAD_ATTACH:

            printf("\nthread attach of dll");

            break;

            case DLL_THREAD_DETACH:

            printf("\nthread detach of dll");

            break;

            case DLL_PROCESS_DETACH:

            printf("\nprocess detach of dll");

            break;

            }

            return TRUE;

            }


              DllMain函數在DLL被加載和卸載時被調用,在單個線程啟動和終止時,DLLMain函數也被調用,ul_reason_for_call指明了被調用的原因。原因共有4種,即PROCESS_ATTACH、PROCESS_DETACH、THREAD_ATTACH和THREAD_DETACH,以switch語句列出。
            來仔細解讀一下DllMain的函數頭BOOL APIENTRY DllMain( HANDLE hModule, WORD ul_reason_for_call, LPVOID lpReserved )。

              APIENTRY被定義為__stdcall,它意味著這個函數以標準Pascal的方式進行調用,也就是WINAPI方式;

              進程中的每個DLL模塊被全局唯一的32字節的HINSTANCE句柄標識,只有在特定的進程內部有效,句柄代表了DLL模塊在進程虛擬空間中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,這兩種類型可以替換使用,這就是函數參數hModule的來歷。

              執行下列代碼:

            hDll = LoadLibrary("..\\Debug\\dllTest.dll");

            if (hDll != NULL)

            {

            addFun = (lpAddFun)GetProcAddress(hDll, MAKEINTRESOURCE(1));

            //MAKEINTRESOURCE直接使用導出文件中的序號

            if (addFun != NULL)

            {

            int result = addFun(2, 3);

            printf("\ncall add in dll:%d", result);

            }

            FreeLibrary(hDll);

            }



              我們看到輸出順序為:

              process attach of dll

              call add in dll:5

              process detach of dll

              這一輸出順序驗證了DllMain被調用的時機。

              代碼中的GetProcAddress ( hDll, MAKEINTRESOURCE ( 1 ) )值得留意,它直接通過.def文件中為add函數指定的順序號訪問add函數,具體體現在MAKEINTRESOURCE ( 1 ),MAKEINTRESOURCE是一個通過序號獲取函數名的宏,定義為(節選自winuser.h):

            #define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))

            #define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))

            #ifdef UNICODE

            #define MAKEINTRESOURCE MAKEINTRESOURCEW

            #else

            #define MAKEINTRESOURCE MAKEINTRESOURCEA

            Posted on 2005-11-25 18:12 艾凡赫 閱讀(7623) 評論(0)  編輯 收藏 引用 所屬分類: DLL 技術
            欧美激情精品久久久久久久九九九 | 无码精品久久久久久人妻中字 | 亚洲午夜精品久久久久久人妖| 超级97碰碰碰碰久久久久最新| 国产精品久久久久一区二区三区| 久久精品国产亚洲AV无码娇色| 色8久久人人97超碰香蕉987| 国产69精品久久久久久人妻精品| 99精品国产免费久久久久久下载| 亚洲国产精品无码久久久久久曰| 理论片午午伦夜理片久久| 日韩久久久久中文字幕人妻 | 亚洲人成精品久久久久| 久久久久亚洲av综合波多野结衣 | 国产精品热久久无码av| 国产亚州精品女人久久久久久| 草草久久久无码国产专区| 久久99精品国产麻豆蜜芽| 久久高潮一级毛片免费| 亚洲午夜精品久久久久久浪潮 | 国内精品久久久久久99蜜桃| 激情伊人五月天久久综合| 亚洲国产成人久久综合一| 久久久WWW成人免费毛片| 欧美日韩精品久久久久| 久久精品无码一区二区WWW| 午夜欧美精品久久久久久久| 91久久婷婷国产综合精品青草| 伊人色综合久久| 久久青青草视频| 亚洲伊人久久精品影院| 狠色狠色狠狠色综合久久| 国产日韩久久免费影院| 2020国产成人久久精品| 国产精品久久久久无码av| 性欧美大战久久久久久久 | 久久精品天天中文字幕人妻| 国产叼嘿久久精品久久| 99精品久久久久久久婷婷| 久久精品国产秦先生| 狠狠色丁香久久婷婷综合蜜芽五月|