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

Where there is a dream ,there is hope

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

常用鏈接

留言簿(1)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

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

1:神馬是Dll和Lib,神馬是靜態(tài)鏈接和動(dòng)態(tài)鏈接

大家都懂的,DLL就是動(dòng)態(tài)鏈接庫,LIB是靜態(tài)鏈接庫。DLL其實(shí)就是EXE,只不過沒main。

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

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

 

2:DLL和LIB區(qū)別和聯(lián)系。

DLL是程序在運(yùn)行階段才需要的文件。

LIB是程序編譯時(shí)需要鏈接的文件。

DLL只有一種,其中一定是函數(shù)和過程的實(shí)現(xiàn)。

LIB是有兩種。若只生成LIB的話,則這個(gè)LIB是靜態(tài)編譯出來的,它內(nèi)部包含了函數(shù)索引以及實(shí)現(xiàn),這個(gè)LIB會(huì)比較大。若生成DLL的話,則也會(huì)生成一個(gè)LIB,這個(gè)LIB和剛才那個(gè)LIB不同,它是只有函數(shù)索引,沒有實(shí)現(xiàn)的,它很小。但是這倆LIB依然遵循上個(gè)原則,是在編譯時(shí)候是需要被鏈接的。若不鏈接第一個(gè)LIB的話,在程序運(yùn)行時(shí)會(huì)無法找到函數(shù)實(shí)現(xiàn),當(dāng)?shù)簟H舨绘溄拥诙€(gè)LIB的話,在程序運(yùn)行時(shí)依然會(huì)無法找到函數(shù)實(shí)現(xiàn)。但第二種LIB有一種替代方式,就是在程序里,使用LoadLibrary,GetProcAddress替代第二個(gè)LIB的功能。第一種LIB生成的EXE文件會(huì)很大,因?yàn)長IB所有信息被靜態(tài)鏈接進(jìn)EXE里了。第二種LIB生成的EXE文件會(huì)比較小,因?yàn)楹瘮?shù)過程實(shí)現(xiàn)依舊在DLL內(nèi)。

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

靜態(tài)鏈接LIB的優(yōu)點(diǎn)是免除掛接動(dòng)態(tài)鏈接庫,缺點(diǎn)是EXE大,版本控制麻煩些。

動(dòng)態(tài)鏈接DLL的優(yōu)點(diǎn)是文件小,版本更換時(shí)換DLL就好了,缺點(diǎn)是多了點(diǎn)文件。動(dòng)態(tài)鏈接若是被多個(gè)進(jìn)程使用,會(huì)更加方便和節(jié)省內(nèi)存。

 

3:為什么編譯DLL時(shí)總會(huì)同時(shí)生成一個(gè)LIB?這個(gè)LIB有用嗎?

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

當(dāng)然,若我們的應(yīng)用程序里不鏈接這個(gè)LIB,則可以使用LoadLibrary,GetProcAddress來告訴系統(tǒng)我們在運(yùn)行時(shí)需要怎么著DLL以及其內(nèi)的函數(shù)。

 

4:DLL意義。

1:DLL真正實(shí)現(xiàn)了跨語言。各種語言都可以生成DLL,而對系統(tǒng)以及應(yīng)用程序來說,哪種語言生成的DLL是沒有區(qū)別的。

2:DLL有足夠的封裝性,對于版本更新有很大好處。因?yàn)镈LL是運(yùn)行期間才會(huì)使用,所以,即使DLL內(nèi)函數(shù)實(shí)現(xiàn)有變化(只要參數(shù)和返回值不發(fā)生變化),程序是不需要進(jìn)行編譯的。大大提高了軟件開發(fā)和維護(hù)的效率。

3:DLL被多個(gè)進(jìn)程使用,因?yàn)橛袃?nèi)存映射機(jī)制,無需占用更多內(nèi)存。

 

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

每個(gè)應(yīng)用程序必須有一個(gè)main或者winmain函數(shù)作為入口,DLL一樣,有自己的缺省的入口函數(shù),就是DllMain。函數(shù)如下

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:   // 進(jìn)程被調(diào)用
 case DLL_THREAD_ATTACH:     // 線程被調(diào)用
 case DLL_THREAD_DETACH:   // 線程被停止
 case DLL_PROCESS_DETACH:  // 進(jìn)程被停止
  break;
 }
 return TRUE;
}

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

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

但是有查看過DLL代碼的人員都會(huì)經(jīng)常見到這么一段代碼

#ifdef FK_DLL_EXPORTS

#define FK_DLL __declspec( dllexport )

#else

#define FK_DLL __declspec( dllimport )

#endif

意義很明顯,但是,問題是  FK_DLL_EXPORTS 這個(gè)宏是應(yīng)該在哪兒定義呢?在DLL項(xiàng)目內(nèi),還是在使用DLL的應(yīng)用程序內(nèi)?

這點(diǎn)某志曾迷糊很久,呵呵~其實(shí)后來想想,還是蠻明確的。export是導(dǎo)出。import是導(dǎo)入。對于DLL來說,是要導(dǎo)出這些函數(shù)給其他應(yīng)用程序使用的,所以應(yīng)當(dāng)定義 FK_DLL_EXPORTS 宏。對于使用DLL的應(yīng)用程序來說,是導(dǎo)入,是無需定義的。

使用時(shí)候也很簡單。

class FK_DLL CMyDllClass{} ;

則整個(gè)類被導(dǎo)出。

FK_DLL void MyTestFun( int a );

則該函數(shù)被導(dǎo)出。

但是有時(shí)我們可以見到這樣的代碼

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

其中extern "C"的原理就是標(biāo)示該函數(shù)要求以C形式去進(jìn)行編譯,不要以C++形式去編譯。具體的編譯原理就不羅嗦了,簡而言之,被extern "C"定義函數(shù),可以被C以及其他語言進(jìn)行DLL調(diào)用,而未被extern "C"定義的函數(shù),C是無法訪問DLL中這個(gè)函數(shù)的。

 

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

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

FKDll.def里加入以下代碼

LIBRARY FKDll

EXPORTS

MyTestFun@1

MyTestFun2@2

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

 

6:使用DLL

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

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

顯式鏈接則麻煩些。在程序中使用LoadLibrary加載DLL,再GetProcAddress獲取函數(shù)實(shí)現(xiàn),在程序退出之前,調(diào)用FreeLibrary來動(dòng)態(tài)釋放掉鏈接庫。

‍例如:

void Main()

{

     typedef void (*FKDllFun1)(int a);

    FKDllFun1 pFun1;

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

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

    pFun1( 100 );

    FreeLibrary(hDll);

}

當(dāng)然,我們剛才.def里面還指定了導(dǎo)出函數(shù)的導(dǎo)出順序,那么我們可以修改里面獲取函數(shù)指針那一段為

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

這樣可以更快,但是別將編號(hào)記混了,會(huì)導(dǎo)致詭異的錯(cuò)誤。

 

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

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

顯式鏈接可以在程序執(zhí)行時(shí)動(dòng)態(tài)的加載DLL和卸載DLL文件,隱式鏈接是做不到的。

顯式鏈接LoadLibrary,GetProcAddress時(shí)能獲知是否加載失敗,我們可以對其進(jìn)行檢查錯(cuò)誤處理。而顯式鏈接可能是一個(gè)很惡劣的提示或是程序崩潰的結(jié)果。

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

例如:

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

{

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

}

 

8:導(dǎo)出類和導(dǎo)出函數(shù)

類和函數(shù)的導(dǎo)出方式上面給出了說明,原本極其類似的。

我們說下使用導(dǎo)出類。

若我們隱式的使用了一個(gè)導(dǎo)出類,則我們在應(yīng)用程序里繼承它的時(shí)候,就如同該類就在應(yīng)用程序代碼里一樣,無需任何處理。

例如:

class FK_DLL CMyDllClass{} ;    // Dll文件內(nèi)的代碼

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

class CAppClass : public CMyDllClass      // 應(yīng)用程序內(nèi)代碼,無需做任何處理。

{

       ....

}

也可以直接使用DLL導(dǎo)出類

void main

{

     CMyDllClass* pClass = new CMyDllClass ();

}

但是,若應(yīng)用程序聲明或者分類一個(gè)DLL中導(dǎo)出類的對象時(shí)會(huì)存在一個(gè)很討厭的問題:這個(gè)操作會(huì)使內(nèi)存跟蹤系統(tǒng)失效,使其錯(cuò)誤的報(bào)告內(nèi)存分配和釋放情況。

為解決這個(gè)問題,我們可以給出兩個(gè)接口函數(shù)對DLL導(dǎo)出類進(jìn)行創(chuàng)建銷毀支持,就可以使內(nèi)存跟蹤系統(tǒng)正常了。例如

class FK_DLL CMyDllClass{} ; 

額外增加倆函數(shù)

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

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

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

上面的方法可以正確進(jìn)行內(nèi)存跟蹤了,但是,因?yàn)镈LL導(dǎo)出類CMyDllClass依舊是導(dǎo)出的狀態(tài),用戶同樣可以跳過我們提供的接口直接使用。那么怎么辦呢。方法是不再對類進(jìn)行DLL導(dǎo)出,而對類內(nèi)的函數(shù)全部進(jìn)行DLL導(dǎo)出即可,

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

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

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

同樣,我們也可以發(fā)現(xiàn),在不導(dǎo)出DLL類本身,而只導(dǎo)出DLL類內(nèi)函數(shù)也有一些好處,一些我們不希望外界知道的函數(shù)可以不設(shè)置導(dǎo)出標(biāo)記,這進(jìn)一步保護(hù)了DLL內(nèi)函數(shù)的安全性。

 

9:復(fù)雜問題。

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

class CMyDllClass

{

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

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

}

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

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

class CAppClass : public CMyDllClass      // 應(yīng)用程序內(nèi)代碼,無需做任何處理。

{

       ....

}


posted on 2011-01-17 11:55 IT菜鳥 閱讀(592) 評論(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>
            国产日韩专区| 久久综合一区| 久久久久久国产精品mv| 亚洲欧美国产精品桃花| 香蕉成人伊视频在线观看| 亚洲性线免费观看视频成熟| 亚洲一区三区在线观看| 亚洲欧美在线一区二区| 久久激情五月婷婷| 欧美电影免费观看| 一区二区三区**美女毛片| 午夜综合激情| 欧美精品国产| 国产精品视频免费观看| 国产亚洲欧美另类中文| 91久久亚洲| 亚洲综合999| 美女精品在线| 一区二区三区视频在线播放| 久久国产加勒比精品无码| 欧美成人一区二区| 国产精品视频九色porn| 亚洲韩国青草视频| 亚洲欧美区自拍先锋| 欧美国产高潮xxxx1819| 午夜精品久久久久影视 | 99精品视频免费观看视频| 久久精品国产2020观看福利| 麻豆国产精品va在线观看不卡| 欧美日韩免费视频| 激情综合五月天| 亚洲一区日韩在线| 亚洲国内自拍| 欧美一区二区三区久久精品茉莉花 | 欧美色欧美亚洲高清在线视频| 国产色产综合色产在线视频| 中日韩视频在线观看| 免费在线看成人av| 亚洲欧洲av一区二区| 欧美巨乳在线| 亚洲精品乱码久久久久久蜜桃91| 久久久7777| 亚洲一区在线视频| 欧美国产欧美亚洲国产日韩mv天天看完整 | 好吊成人免视频| 亚洲在线观看视频网站| 亚洲国产美女精品久久久久∴| 欧美与欧洲交xxxx免费观看| 国产精品视频午夜| 亚洲综合色在线| 在线一区免费观看| 欧美日韩黄视频| 99视频在线精品国自产拍免费观看| 欧美高清在线视频| 免费观看30秒视频久久| 亚洲福利视频一区| 奶水喷射视频一区| 久热精品在线视频| 亚洲国产影院| 亚洲国产成人在线播放| 欧美xxxx在线观看| 亚洲精品一区二区三区在线观看 | 欧美激情一区二区在线| 久久精品二区三区| 国内视频一区| 另类尿喷潮videofree| 久久这里有精品15一区二区三区| 影音先锋中文字幕一区| 欧美福利视频| 欧美国产日本在线| 亚洲天堂成人在线观看| 久久激情中文| 亚洲日本免费| 欧美日韩一区在线观看视频| 一区二区三区国产在线| 一本色道久久综合| 国产裸体写真av一区二区| 久久成人精品一区二区三区| 久久精品人人做人人综合| 亚洲成色777777女色窝| 亚洲国产成人精品女人久久久| 欧美日韩大片一区二区三区| 亚洲在线观看视频| 久久精品99国产精品酒店日本| 在线视频观看日韩| 亚洲精品乱码久久久久久蜜桃麻豆 | 午夜综合激情| 亚洲韩日在线| 亚洲无线一线二线三线区别av| 国产日本欧美一区二区三区| 欧美高清影院| 国产欧美 在线欧美| 欧美激情中文字幕一区二区 | 免费在线亚洲| 午夜精品久久久久久久99黑人| 久久国产欧美| 一区二区三区欧美成人| 欧美资源在线观看| 99精品国产福利在线观看免费| 亚洲欧美日本精品| 999在线观看精品免费不卡网站| 亚洲欧美在线视频观看| 日韩视频欧美视频| 久久国产加勒比精品无码| 亚洲图片欧洲图片日韩av| 久久精品欧美日韩精品| 香蕉精品999视频一区二区| 欧美成人a视频| 久热成人在线视频| 国产伦精品一区二区三| 亚洲精品乱码久久久久久久久| 激情综合网址| 欧美一区视频在线| 亚洲女女女同性video| 欧美好骚综合网| 欧美α欧美αv大片| 国产一区二区三区四区| 亚洲一区二区黄| 亚洲一区在线看| 欧美日韩精品高清| 亚洲精品欧美激情| 亚洲精品一区二区三区99| 久久频这里精品99香蕉| 久久久精品999| 国产伦精品免费视频| 亚洲欧美精品伊人久久| 亚洲欧美日韩第一区| 欧美系列亚洲系列| 一区二区欧美在线| 亚洲免费影视第一页| 国产综合婷婷| 免费欧美电影| 狠狠操狠狠色综合网| 欧美亚洲日本国产| 久久国产日韩| 国产视频一区免费看| 亚洲欧美精品一区| 欧美一区观看| 国产三级精品三级| 欧美一区二区精品| 毛片基地黄久久久久久天堂| 尤妮丝一区二区裸体视频| 久久免费99精品久久久久久| 久久综合久久综合这里只有精品| 黄色一区二区在线观看| 久久综合电影| 亚洲精品在线视频观看| 亚洲一级网站| 国产私拍一区| 久久人人爽人人爽爽久久| 欧美电影在线观看| 夜夜嗨av一区二区三区| 国产精品久久久久毛片软件| 午夜久久电影网| 欧美www在线| 亚洲无限av看| 国产婷婷一区二区| 免费不卡欧美自拍视频| 日韩亚洲欧美中文三级| 欧美怡红院视频一区二区三区| 黄色一区二区三区| 欧美日韩国产欧| 性久久久久久久| 亚洲电影免费观看高清完整版| 亚洲一区二区视频在线观看| 国产色综合久久| 欧美日本一道本在线视频| 亚洲欧美激情精品一区二区| 欧美va天堂| 亚洲欧美日韩在线| 亚洲国产精品成人一区二区| 国产精品家庭影院| 美女啪啪无遮挡免费久久网站| 在线亚洲免费视频| 欧美成人综合网站| 亚洲制服丝袜在线| 91久久精品国产91性色tv| 国产精品稀缺呦系列在线| 欧美福利视频一区| 欧美一区二区高清在线观看| 亚洲三级国产| 久久资源在线| 新狼窝色av性久久久久久| 亚洲精品一区久久久久久| 国产精品一区二区三区成人| 欧美韩日一区二区三区| 久久久国产视频91| 亚洲女女女同性video| 亚洲国产欧美国产综合一区| 久久久精品国产免费观看同学| 亚洲视频欧美在线| 亚洲国产综合视频在线观看| 激情国产一区| 国产亚洲一区在线| 国产精品二区在线观看| 欧美精品www| 欧美成人在线免费视频| 久久精品91| 久久精品国产99国产精品澳门| 亚洲免费视频在线观看|