【windows核心編程】DLL相關

來源:互聯網
上載者:User

標籤:c   style   class   blog   code   java   

 

DLL相關的東西

 

1、DLL的載入方式

隱式:

#pragma comment(lib, "XX.lib");

編譯器去尋找名為XX.dll的DLL,除了名字相同,該DLL和該LIB的GUID也相同。

 

顯式:

HINSTANCE   hInst = LoadLibrary(TEXT("XX.dll"));

if(NULL == hInst)  retrun;

 

HINSTANCE hInst = LoadLibrary(TEXT("XX.dll"), NULL,   FLAGS);

第三個參數為一些標誌,詳見核心編程。

 

2、DLL的入口函數

原型

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
);

其中hModule為該DLL在當前進程地址空間中的位置,ul_reason_for_call為調用此函數的原因,lpReserved如果為明確式載入則為0,如果為隱式載入則為非0。

詳細說一下ul_reason_for_call

BOOL APIENTRY DllMain( HMODULE hModule,                       DWORD  ul_reason_for_call,                       LPVOID lpReserved                     ){#ifdef _DEBUG    switch (ul_reason_for_call)    {        //只在該DLL第一次載入進地址空間的時候被調用一次        //此後當該DLL被載入進不同進程的地址空間時讓然不調用        //當主調線程通過該reason調用DllMain函數時,主調線程不會收到DLL_THREAD_ATTACH通知    case DLL_PROCESS_ATTACH:        OutputDebugString(TEXT("\r\n***********B Dll DLL_PROCESS_ATTACH ***********\r\n"));        break;        //當該DLL已經被載入到進程地址空間後,當有新【線程建立】的時候,新建立的線程先執行此段代碼        //然後再去執行線程本身的代碼        //不管有幾個DLL,每個DLL的此處代碼都會被新線程執行    case DLL_THREAD_ATTACH:        OutputDebugString(TEXT("\r\n***********B Dll DLL_THREAD_ATTACH ***********\r\n"));        break;        //當該DLL已經被載入到進程地址空間後,當有【線程結束】的時候,該線程結束之前會調用此處代碼        //然後才返回        //不管有幾個DLL,每個DLL的此處代碼都會被執行    case DLL_THREAD_DETACH:        OutputDebugString(TEXT("\r\n***********B Dll DLL_THREAD_DETACH *********** \r\n"));        break;        //只有在該DLL從記憶體中卸載的時候才會被調用一次     case  DLL_PROCESS_DETACH:        OutputDebugString(TEXT("\r\n***********B Dll DLL_PROCESS_DETACH ***********\r\n"));        break;    }#endif    return TRUE;}

 

 

demo

有兩個DLL, ADll.dll 和 BDll.dll

在程式中載入這個兩個DLL, 然後建立一個新線程,看輸出

//載入DLLvoid CUseABDllDlg::OnBnClickedBtnLoadlib(){    HINSTANCE hInstA = LoadLibrary(_T("ADll.dll"));    HINSTANCE HIntB = LoadLibrary(_T("BDll.dll"));    if (NULL == hInstA || NULL == HIntB)    {        AfxMessageBox(_T("載入DLL失敗"));        return;    }  }//線程函數UINT WINAPI WorkThread(LPVOID lpParam){#ifdef _DEBUG    OutputDebugString(TEXT("\r\n&&&&&&&&&&&&&&&&&&線程被建立&&&&&&&&&&&&&&&&&\r\n"));#endif    return 0U;}//建立線程void CUseABDllDlg::OnBnClickedButton2(){    HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, WorkThread, NULL, 0, NULL);    if (NULL == hThread || INVALID_HANDLE_VALUE == hThread)    {        AfxMessageBox(_T("建立線程失敗"));    }}

 

 

輸出

 

結論:

每建立一個新線程,當前進程地址空間中的DLL的DllMain函數都會通過DLL_THREAD_ATTACH通知被調用一次

每結束一個線程,進程地址空間空的DLL的DllMain函數都會通過DLL_THREAD_DETACH通知被調用一次。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.