青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Where there is a dream ,there is hope

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  64 Posts :: 0 Stories :: 8 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

原文地址:http://hi.baidu.com/freedomknightduzhi/blog/item/a0504560d1277555ebf8f8ff.html

1:神馬是Dll和Lib,神馬是靜態鏈接和動態鏈接

大家都懂的,DLL就是動態鏈接庫,LIB是靜態鏈接庫。DLL其實就是EXE,只不過沒main。

動態鏈接是相對于靜態鏈接而言的。所謂靜態鏈接就是把函數或過程直接鏈接到可執行文件中,成為可執行程序中的一部分,當多個程序調用同樣的函數時,內存里就會有這個函數的多個拷貝,浪費內存資源。而動態鏈接則是提供了一個函數的描述信息給可執行文件(并沒有內存拷貝),當程序被夾在到內存里開始運行的時候,系統會在底層創建DLL和應用程序之間的連接關系,當執行期間需要調用DLL函數時,系統才會真正根據鏈接的定位信息去執行DLL中的函數代碼。

在WINDOWS32系統底下,每個進程有自己的32位的線性地址空間,若一個DLL被進程使用,則該DLL首先會被調入WIN32系統的全局堆棧,然后通過內存映射文件方式映射到這個DLL的進程地址空間。若一個DLL被多個進程調用,則每個進程都會接收到該DLL的一個映像,而非多份的拷貝。但,在WIN16系統下,每個進程需要擁有自己的一份DLL空間,可以理解為何靜態鏈接沒啥區別。

 

2:DLL和LIB區別和聯系。

DLL是程序在運行階段才需要的文件。

LIB是程序編譯時需要鏈接的文件。

DLL只有一種,其中一定是函數和過程的實現。

LIB是有兩種。若只生成LIB的話,則這個LIB是靜態編譯出來的,它內部包含了函數索引以及實現,這個LIB會比較大。若生成DLL的話,則也會生成一個LIB,這個LIB和剛才那個LIB不同,它是只有函數索引,沒有實現的,它很小。但是這倆LIB依然遵循上個原則,是在編譯時候是需要被鏈接的。若不鏈接第一個LIB的話,在程序運行時會無法找到函數實現,當掉。若不鏈接第二個LIB的話,在程序運行時依然會無法找到函數實現。但第二種LIB有一種替代方式,就是在程序里,使用LoadLibrary,GetProcAddress替代第二個LIB的功能。第一種LIB生成的EXE文件會很大,因為LIB所有信息被靜態鏈接進EXE里了。第二種LIB生成的EXE文件會比較小,因為函數過程實現依舊在DLL內。

(啰嗦了一堆,某志希望大家能夠明白兩個LIB的區別。要再不行的話,我們可以將靜態編譯的LIB稱為 靜態鏈接庫。但動態編譯的LIB稱為 引入庫。可能會比較好一些。)

靜態鏈接LIB的優點是免除掛接動態鏈接庫,缺點是EXE大,版本控制麻煩些。

動態鏈接DLL的優點是文件小,版本更換時換DLL就好了,缺點是多了點文件。動態鏈接若是被多個進程使用,會更加方便和節省內存。

 

3:為什么編譯DLL時總會同時生成一個LIB?這個LIB有用嗎?

若我們不是用靜態鏈接,而使用DLL,那么我們也需要一個LIB,這個LIB的作用是被鏈接到程序里,在程序運行時告訴系統你需要什么DLL文件。這個LIB里保存的是DLL的名字和輸出函數入口的順序表。它是有意義的。

當然,若我們的應用程序里不鏈接這個LIB,則可以使用LoadLibrary,GetProcAddress來告訴系統我們在運行時需要怎么著DLL以及其內的函數。

 

4:DLL意義。

1:DLL真正實現了跨語言。各種語言都可以生成DLL,而對系統以及應用程序來說,哪種語言生成的DLL是沒有區別的。

2:DLL有足夠的封裝性,對于版本更新有很大好處。因為DLL是運行期間才會使用,所以,即使DLL內函數實現有變化(只要參數和返回值不發生變化),程序是不需要進行編譯的。大大提高了軟件開發和維護的效率。

3:DLL被多個進程使用,因為有內存映射機制,無需占用更多內存。

 

5:創建DLL。(注意:某志就不再講解使用MFC AppWizard[dll] 方式創建DLL了。有興趣的自己去百度。這里創建DLL只指使用Win32 Dynamic-link Library創建Non-MFC DLL。呃,DLL的三種類型就不解釋了,依舊那句話:百度一下你就知道。)

每個應用程序必須有一個main或者winmain函數作為入口,DLL一樣,有自己的缺省的入口函數,就是DllMain。函數如下

BOOL APIENTRY DllMain( HMODULE 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:  // 進程被停止
  break;
 }
 return TRUE;
}

一般情況下,我們不需要對這個缺省的入口函數進行什么修改,它就會使動態鏈接庫得到正確的初始化。但是,當我們的DLL需要額外分配內存或者資源的時候,或者,DLL希望對調用自己的進程或線程進行初始化或清除的額外操作時,可以在上述代碼case中加一些自己感冒的東東。(懶……不想細寫了- -Orz,現在是晚上2點了,明天還一堆的事情)

DLL對于導出類和導出函數沒啥不同。只要加上 __declspec( dllexport ) 修飾函數或者類就好了。

但是有查看過DLL代碼的人員都會經常見到這么一段代碼

#ifdef FK_DLL_EXPORTS

#define FK_DLL __declspec( dllexport )

#else

#define FK_DLL __declspec( dllimport )

#endif

意義很明顯,但是,問題是  FK_DLL_EXPORTS 這個宏是應該在哪兒定義呢?在DLL項目內,還是在使用DLL的應用程序內?

這點某志曾迷糊很久,呵呵~其實后來想想,還是蠻明確的。export是導出。import是導入。對于DLL來說,是要導出這些函數給其他應用程序使用的,所以應當定義 FK_DLL_EXPORTS 宏。對于使用DLL的應用程序來說,是導入,是無需定義的。

使用時候也很簡單。

class FK_DLL CMyDllClass{} ;

則整個類被導出。

FK_DLL void MyTestFun( int a );

則該函數被導出。

但是有時我們可以見到這樣的代碼

extern "C" FK_DLL void MyTestFun2( float b );

其中extern "C"的原理就是標示該函數要求以C形式去進行編譯,不要以C++形式去編譯。具體的編譯原理就不羅嗦了,簡而言之,被extern "C"定義函數,可以被C以及其他語言進行DLL調用,而未被extern "C"定義的函數,C是無法訪問DLL中這個函數的。

 

在VS中開發DLL還有一種方式,使用.def文件。

新建個文本文檔,改后綴為FKDll.def,加入到工程里。

FKDll.def里加入以下代碼

LIBRARY FKDll

EXPORTS

MyTestFun@1

MyTestFun2@2

就可以了。其中,LIBRARY語句是說明.def文件是屬于FKDll這個Dll的。EXPORTS下面是我們需要導出的函數名。后面加的@+數字,是表示導出函數的順序編號。這樣就足夠了。(詳細的自己百度,好困,zzzZZZ)

 

6:使用DLL

使用DLL有兩種方式。顯式鏈接和隱式鏈接。

隱式鏈接很容易。直接#progam comment(lib, "FKDll.lib") 就可以。當然,也可以在項目工程->屬性->鏈接庫里加上庫和路徑(相對路徑和絕對路徑都可以)。

顯式鏈接則麻煩些。在程序中使用LoadLibrary加載DLL,再GetProcAddress獲取函數實現,在程序退出之前,調用FreeLibrary來動態釋放掉鏈接庫。

‍例如:

void Main()

{

     typedef void (*FKDllFun1)(int a);

    FKDllFun1 pFun1;

    HINSTANCE hDLL  = LoadLibrary("FKDll.dll");   // 若hDll為空則讀取Dll失敗。

    pFun1 = (pFun1)GetProcAddress(hDll, "MyTestFun1" );   // 從應用程序中的DLL鏡像中獲取名為 MyTestFun1 的函數指針

    pFun1( 100 );

    FreeLibrary(hDll);

}

當然,我們剛才.def里面還指定了導出函數的導出順序,那么我們可以修改里面獲取函數指針那一段為

‍pFun1 = (pFun1)GetProcAddress(hDll, MAKEINTERSOURCE(1) );  // 1 是剛才指定的MyTestFun1函數導出順序編號。

這樣可以更快,但是別將編號記混了,會導致詭異的錯誤。

 

7:比較顯式鏈接和隱式鏈接。

可能的話,盡量使用顯式鏈接。

顯式鏈接可以在程序執行時動態的加載DLL和卸載DLL文件,隱式鏈接是做不到的。

顯式鏈接LoadLibrary,GetProcAddress時能獲知是否加載失敗,我們可以對其進行檢查錯誤處理。而顯式鏈接可能是一個很惡劣的提示或是程序崩潰的結果。

對于有些Ex類型的加強函數,顯式鏈接可以允許我們找到替代方案。也包括選擇D3d9.dll和OpenGL.dll時也可采用同樣處理。

例如:

if( GetProcAddress( hDll, "FKDllFunEx") == NULL )

{

‍    pFun = GetProcAddress( hDll, "FKDllFun");    // 然后使用pFun進行處理

}

 

8:導出類和導出函數

類和函數的導出方式上面給出了說明,原本極其類似的。

我們說下使用導出類。

若我們隱式的使用了一個導出類,則我們在應用程序里繼承它的時候,就如同該類就在應用程序代碼里一樣,無需任何處理。

例如:

class FK_DLL CMyDllClass{} ;    // Dll文件內的代碼

-----------------------

class CAppClass : public CMyDllClass      // 應用程序內代碼,無需做任何處理。

{

       ....

}

也可以直接使用DLL導出類

void main

{

     CMyDllClass* pClass = new CMyDllClass ();

}

但是,若應用程序聲明或者分類一個DLL中導出類的對象時會存在一個很討厭的問題:這個操作會使內存跟蹤系統失效,使其錯誤的報告內存分配和釋放情況。

為解決這個問題,我們可以給出兩個接口函數對DLL導出類進行創建銷毀支持,就可以使內存跟蹤系統正常了。例如

class FK_DLL CMyDllClass{} ; 

額外增加倆函數

FK_DLL CMyDllClass* CreateMyDllClass(){ return new CMyDllClass(); }

FK_DLL void DestoryMyDllClass( CMyDllClass* p_pClass ){ delete p_pClass; }

-----------------------------------------------

上面的方法可以正確進行內存跟蹤了,但是,因為DLL導出類CMyDllClass依舊是導出的狀態,用戶同樣可以跳過我們提供的接口直接使用。那么怎么辦呢。方法是不再對類進行DLL導出,而對類內的函數全部進行DLL導出即可,

-----------------------------------------------

但是若僅僅提供上面兩個接口函數以及類內全部函數,的確功能可以實現,卻無法進行類繼承了。若這個類繼承很重要,必須開放,那么就需要使用新的內存跟蹤程序替換應用程序內的原有內存跟蹤程序。或者使用下面的一個方法。(見模塊9:復雜問題)

-----------------------------------------------

同樣,我們也可以發現,在不導出DLL類本身,而只導出DLL類內函數也有一些好處,一些我們不希望外界知道的函數可以不設置導出標記,這進一步保護了DLL內函數的安全性。

 

9:復雜問題。

若我們使用LoadLibrary顯式加載一個DLL,并嘗試在應用程序中調用一個類內成員函數的話,無論該函數是否在頭文件中有聲明,VS會給出一個"unresolved external symbol(未解析的外部符號)"的錯誤。我們此時可以將項目屬性中的內聯函數擴展選項修改為"Only __inline"或"Any Suitable"即可。但,我們可能在調試連編的時候期望關閉內聯函數擴展,那么另一種解決方案是,將希望導出的函數聲明為虛函數,例如

class CMyDllClass

{

   FK_DLL virtual void MyTestFun( int a ){  dosth(); }  

   // 用上面代碼替換 FK_DLL void MyTestFun( int a ){  dosth(); }  

}

這樣做還有一個額外的好處。將導出的類成員函數設置為虛函數之后,該虛函數所在的類在應用程序中也如同被聲明一樣,可以接受繼承。

例如若是上面的做法,應用程序就可以進行順利繼承,而不必要求CMyDllClass 被標示為導出。(原理不知,希望精通底層的高手協助解釋。)

class CAppClass : public CMyDllClass      // 應用程序內代碼,無需做任何處理。

{

       ....

}


posted on 2011-01-17 11:55 IT菜鳥 閱讀(595) 評論(0)  編輯 收藏 引用 所屬分類: C/C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美韩日一区二区| 亚洲欧美日本国产有色| 亚洲开发第一视频在线播放| 欧美在线日韩精品| 欧美有码在线观看视频| 国产精品视频精品| 亚洲欧美中文字幕| 亚洲一区三区在线观看| 欧美另类videos死尸| 91久久精品国产91性色tv| 美女主播精品视频一二三四| 欧美一区二区女人| 国产日产欧美a一级在线| 久久av资源网| 小处雏高清一区二区三区| 国产目拍亚洲精品99久久精品 | 亚洲第一在线综合网站| 中国女人久久久| 国产精品毛片| 久久久xxx| 久久久久久久久久久成人| 黄色在线一区| 亚洲国产日韩欧美| 欧美日韩亚洲不卡| 亚洲曰本av电影| 午夜精品久久久久久久蜜桃app| 国产一区成人| 美日韩精品视频| 欧美日韩情趣电影| 欧美一二区视频| 久久久久国产精品麻豆ai换脸| 亚洲国产合集| 亚洲国产精品一区二区尤物区| 欧美日韩精品国产| 欧美一区二区视频观看视频| 久久精品国产亚洲精品| 亚洲精品一区二区三区99| 日韩午夜剧场| 韩国女主播一区二区三区| 亚洲欧洲日本国产| 国产精品自拍在线| 亚洲福利专区| 国产精品免费aⅴ片在线观看| 久久先锋资源| 欧美国产在线电影| 欧美一区视频在线| 欧美va亚洲va日韩∨a综合色| 在线一区二区视频| 久久综合久久久| 欧美亚洲在线观看| 欧美高清视频在线| 久久久.com| 欧美激情亚洲激情| 欧美一区影院| 欧美午夜在线一二页| 蜜桃av噜噜一区| 国产精品看片你懂得| 国产精品久久网站| 亚洲精品在线一区二区| 国产精品qvod| 欧美成人蜜桃| 国产在线乱码一区二区三区| 99国产精品久久| 亚洲美女av黄| 欧美+日本+国产+在线a∨观看| 久久福利视频导航| 国产精品久久二区二区| 亚洲激情偷拍| 最近中文字幕mv在线一区二区三区四区 | 蜜桃久久av一区| 久久国产天堂福利天堂| 欧美日韩一区高清| 亚洲激情视频| 亚洲精品影院在线观看| 久久视频免费观看| 蜜桃av噜噜一区| 狠狠干狠狠久久| 欧美在线看片a免费观看| 午夜在线成人av| 国产精品一区视频| 亚洲一区免费看| 性xx色xx综合久久久xx| 欧美性开放视频| 国产精品99久久久久久有的能看| 一区二区av在线| 欧美日韩精品免费观看视频完整| 亚洲日本无吗高清不卡| 日韩一级裸体免费视频| 午夜宅男久久久| 亚洲美女av黄| 欧美麻豆久久久久久中文| 欧美激情欧美狂野欧美精品| 亚洲成人资源网| 欧美久久久久久久久| 日韩视频不卡| 欧美一区2区三区4区公司二百 | 午夜亚洲一区| 久久嫩草精品久久久精品一| 国模精品娜娜一二三区| 久久久亚洲国产天美传媒修理工 | 国语自产精品视频在线看8查询8| 亚洲一区二区在线看| 亚洲一级网站| 国产麻豆精品在线观看| 欧美亚洲一区| 欧美激情一区二区三区成人| 亚洲精品乱码久久久久久黑人| 欧美精品18videos性欧美| 一本色道久久99精品综合| 欧美在线综合视频| 在线看日韩欧美| 欧美日韩精品福利| 欧美在线看片| 亚洲三级色网| 久久精品综合| 亚洲一级二级在线| 亚洲第一页在线| 欧美视频免费| 毛片av中文字幕一区二区| 欧美风情在线观看| 久久国产欧美| 99视频国产精品免费观看| 在线观看视频一区二区| 欧美三级电影网| 久久―日本道色综合久久| 亚洲成色最大综合在线| 国产精品久久久久久久7电影| 美女视频网站黄色亚洲| 午夜视频一区二区| 亚洲精品中文字幕在线| 欧美国产日本| 久久久夜色精品亚洲| 欧美影院在线播放| 亚洲午夜激情在线| 亚洲日本va午夜在线电影| 欧美日韩在线一二三| 农村妇女精品| 久久久伊人欧美| 亚洲主播在线播放| 亚洲理伦电影| 久久久久久亚洲精品中文字幕 | 国产精品普通话对白| 免费在线观看一区二区| 欧美诱惑福利视频| 亚洲在线视频免费观看| 亚洲人成网站在线播| 理论片一区二区在线| 西西人体一区二区| 一区二区三区国产| 狠狠干综合网| 欧美亚男人的天堂| 欧美精品大片| 欧美国产欧美亚州国产日韩mv天天看完整| 亚洲欧美中日韩| 亚洲国产第一页| 久久免费精品视频| 久久狠狠亚洲综合| 欧美一级二级三级蜜桃| 亚洲专区免费| 亚洲午夜小视频| 亚洲一区二区在线| 在线视频你懂得一区二区三区| 亚洲黄色av一区| 黑丝一区二区三区| 国产一区二区三区在线播放免费观看| 欧美激情区在线播放| 欧美高潮视频| 欧美小视频在线| 国产精品区一区二区三区| 国产女同一区二区| 国产亚洲精品一区二区| 精品动漫3d一区二区三区免费版 | 亚洲欧美日韩国产一区二区| 亚洲永久免费| 欧美在线高清视频| 久久久久久久波多野高潮日日 | 新片速递亚洲合集欧美合集| 午夜久久福利| 久久精品免费观看| 美女视频一区免费观看| 欧美国产日韩xxxxx| 91久久精品久久国产性色也91| 亚洲日本va在线观看| 亚洲无限av看| 久久国内精品视频| 欧美黄色影院| 国产精品一区二区女厕厕| 伊人久久亚洲热| 亚洲欧美日韩天堂| 亚洲第一区在线| 欧美一区二区精品久久911| 欧美精品色综合| 激情成人av| 性欧美精品高清| 亚洲精品免费在线播放| 久久久福利视频| 国产精品久久久久影院色老大| 亚洲日韩欧美视频一区| 久久亚洲精品欧美| 亚洲一区欧美|