程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> DLL(Dynamic Link Libraries)全面剖析(2)

DLL(Dynamic Link Libraries)全面剖析(2)

編輯:vc教程
MFC中的DLL
  • Non-MFC DLL:指的是不用 MFC 的類庫結構,直接用 C 語言寫的 DLL,其輸出的函數一般用的是標准 C 接口,並能被 非 MFC 或 MFC 編寫的應用程序所調用。
  • Regular DLL:和下述的 Extension DLLs 一樣,是用 MFC 類庫編寫的。明顯的特點是在源文件裡有一個繼承 CWinApp 的類。其又可細分成靜態連接到 MFC 和動態連接到 MFC 上的。   靜態連接到 MFC 的動態連接庫只被 VC 的專業 版和企業版所支持。該類 DLL 應用程序裡頭的輸出函數可以被任意 Win32 程序使用,包括使用 MFC 的應用程序。輸入函數有如下形式: extern "C" EXPORT YourExportedFunction(); 如果沒有 extern "C" 修飾,輸出函數僅僅能從 C++ 代碼中調用。 DLL 應用程序從 CWinApp 派生,但沒有消息循環。

      動態鏈接到 MFC 的 規則 DLL 應用程序裡頭的輸出函數可以被任意 Win32 程序使用,包括使用 MFC 的應用程序。但是,所有從 DLL 輸出的函數應該以如下語句開始:

    AFX_MANAGE_STATE(AfxGetStaticModuleState( )) 

      此語句用來正確地切換 MFC 模塊狀態。

      Regular DLL能夠被所有支持 DLL 技術的語言所編寫的應用程序所調用。在這種動態連接庫中,它必須有一個從 CWinApp 繼承下來的類,DLLMain 函數被 MFC 所提供,不用自己顯式的寫出來。

  •   Extension DLL:用來實現從 MFC 所繼承下來的類的重新利用,也就是說,用這種類型的動態連接庫,可以用來輸出一個從 MFC 所繼承下來的類。它輸出的函數僅可以被使用 MFC 且動態鏈接到 MFC 的應用程序使用。可以從 MFC 繼承你所想要的、更適於你自己用的類,並把它提供給你的應用程序。你也可隨意的給你的應用程序提供 MFC 或 MFC 繼承類的對象指針。Extension DLL使用 MFC 的動態連接版本所創建的,並且它只被用 MFC 類庫所編寫的應用程序所調用。Extension DLLs 和 Regular DLLs 不一樣,它沒有從 CWinApp 繼承而來的類的對象,所以,你必須為自己 DLLMain 函數添加初始化代碼和結束代碼。

      和規則 DLL 相比,有以下不同:

      1、它沒有從 CWinApp 派生的對象; 2、它必須有一個 DLLMain 函數; 3、DLLMain 調用 AfxInitExtensionModule 函數,必須檢查該函數的返回值,如果返回0,DLLMmain 也返回 0; 4、如果它希望輸出 CRuntimeClass 類型的對象或者資源,則需要提供一個初始化函數來創建一個 CDynLinkLibrary 對象。並且,有必要把初始化函數輸出; 5、使用擴展 DLL 的 MFC 應用程序必須有一個從 CWinApp 派生的類,而且,一般在InitInstance 裡調用擴展 DLL 的初始化函數。

DLL入口函數

  1、每一個 DLL 必須有一個入口點,DLLMain 是一個缺省的入口函數。DLLMain 負責初始化和結束工作,每當一個新的進程或者該進程的新的線程訪問 DLL 時,或者訪問 DLL 的每一個進程或者線程不再使用DLL或者結束時,都會調用 DLLMain。但是,使用 TerminateProcess 或 TerminateThread 結束進程或者線程,不會調用 DLLMain。

  DLLMain的函數原型:

BOOL APIENTRY DLLMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { 	switch(ul_reason_for_call) 	{ 	case DLL_PROCESS_ATTACH: 	....... 	case DLL_THREAD_ATTACH: 	....... 	case DLL_THREAD_DETACH: 	....... 	case DLL_PROCESS_DETACH: 	....... 	return TRUE; 	} } 

  參數:

  hMoudle:是動態庫被調用時所傳遞來的一個指向自己的句柄(實際上,它是指向_DGROUP段的一個選擇符); ul_reason_for_call:是一個說明動態庫被調原因的標志。當進程或線程裝入或卸載動態連接庫的時候,操作系統調用入口函數,並說明動態連接庫被調用的原因。它所有的可能值為: DLL_PROCESS_ATTACH: 進程被調用; DLL_THREAD_ATTACH: 線程被調用; DLL_PROCESS_DETACH: 進程被停止; DLL_THREAD_DETACH: 線程被停止;

  lpReserved:是一個被系統所保留的參數;

  2、_DLLMainCRTStartup

  為了使用 "C" 運行庫 (CRT,C Run time Library) 的 DLL 版本(多線程),一個 DLL 應用程序必須指定 _DLLMainCRTStartup 為入口函數,DLL 的初始化函數必須是 DLLMain。   _DLLMainCRTStartup 完成以下任務:當進程或線程捆綁(Attach) 到 DLL 時為 "C" 運行時的數據 (C Runtime Data) 分配空間和初始化並且構造全局 "C++"對象,當進程或者線程終止使用DLL(Detach) 時,清理 C Runtime Data 並且銷毀全局 "C++" 對象。它還調用 DLLMain 和 RawDLLMain 函數。   RawDLLMain 在 DLL 應用程序動態鏈接到 MFC DLL 時被需要,但它是靜態鏈接到 DLL 應用程序的。在講述狀態管理時解釋其原因。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved