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

weibing

隨想Visual C++ “導出/導入類的嚴重危害”

VC中有一個關鍵字__declspec(dllexport), 其目的很簡單,就是導出符號,供其它可執行模塊使用,主要用于動態鏈接庫(DLL), 然而也可用于EXE模塊

與此相對應,__declspec(dllimport), 將指明由動態鏈接庫導入符號,除了導入全局變量/類的靜態成員變量,很多時候可以忽略, 這個時候尋找符號的優先級將有所不同
 

當這兩個關鍵字配合類使用,將會產生比較尷尬的問題了

 

DLL:

struct __declspec(dllexport) A

{

    void TestInline()

{

    printf(from dll\n);

}

};

 

EXE:

struct __declspec(dllimport) A

{

void TestInline()

{

printf(from exe\n);

}

};

 

int main()

{

    A obj;

    obj.TestInline(); //輸出 from dll!

 

    return 0;

}

 

危害1:

A中的內聯函數全部失效

 

這當然可以從符號鏈接表中發現鏈接符號的蹤跡來表明內聯函數失效了,不過有一個更簡單的方法,我們可以在EXE的代碼中把TestInline內聯函數的定義代碼加以簡單修改,讓其輸出其它的字符串測試,這個時候運行會發現,輸出的字符串仍然是from dll(注意編譯為Release發行版, DEBUG版會將內聯函數作為普通函數處理), 這就說明了,內聯函數被完全忽略了。如果這個時候,還能想到TestInline的定義代碼還有什么作用的話,那就是白白消耗編譯的時間,編譯期間編譯器辛辛苦苦生成的代碼,鏈接器會毫不留情地忽略掉。

 

很顯然,忽略掉內聯函數的代碼,會有一個直接的副作用,那就是使應用程序的運行期變緩慢,特別是內聯函數被大量在循環內調用,而這個內聯當成普通函數處理了

 

C++運行庫中有大量的內聯成員函數,除了模板類以外(當然,非完全特化的模板類不可能支持導出的),基本上都是以導出類的形式導出,這樣也就意味著,動態鏈接C++運行庫的程序,這類內聯函數全部失效,編譯時間可一點沒少。

 

危害2:

私有成員函數,以及原本不想導出的函數(沒有多少重用價值,導出后還要承擔維護版本兼容性的責任),也被”不知不覺”
地導出了,對于私有(private)成員函數, 導出到外面有什么用呢?占據了符號表的一個位置,可是誰又能調用到呢?
如果要想調用,看來要強制把private變為public了,但是VC的符號形成機制包含了public/private/protected,
也就是通過了編譯也無法通過鏈接,唯一可能的辦法就是,修改DLL頭文件,在類里面增加”friend”, 在EXE端,
改變共享庫DLL頭文件的辦法,很顯然不是個正規方案

另外,導出了這些“無法調用”的函數,也影響了鏈接器的優化。對于這些函數,如果DLL模塊內部也沒有調用到,
本可以完全把這些代碼優化掉,但是由于導出,鏈接器將無能為力, 這也直接增加了DLL文件的體積

由此想到的:

MFC/ATL動態庫似乎了解到這個問題,所以,它們寧可一個一個成員函數進行符號導出,也沒有進行整個類的導出,
為什么它們不把這個方式推薦給VC動態運行庫呢?

VC傳統靜態鏈接運行庫的方式雖然有某種弊端,但是卻可以完全避開上述提到的問題,而且脫離了版本型DLL的依賴(MSVCR71.dll, MSVCP71.dll, MSVCR90.dll, MSVCP90.dll), 對于這類DLL的依賴,將給以后程序升級帶來隱含并難以解決的問題,大家可以考慮如下情形

版本1:A.exe依賴于B.dll, 并且它們同時依賴于msvcp71.dll

版本2: 由于A采用了新的VC版本進行編譯,A.exe現在依賴于msvcp90.dll了,B.dll沒有升級,仍然依賴msvcp71.dll

這個時候,進程中的內存結構產生了微妙的變化,舉例來說,原來msvcp71.dll中的全局變量(例如cout)同時被A.exe和B.dll使用。現在呢,A.exe使用的是msvcp90.dll中的cout, B.dll使用的還是msvcp71.dll中的cout, 這種耦合的變化,將會導致程序執行邏輯的變化(如果你運氣好,也許會沒有問題的),例如,如果你在A中設置了cout的格式,然后調用B的接口,最后B的接口通過cout輸出,版本2與版本1將會拿到不同的執行效果(源代碼可一點沒變哦,僅僅是換了個編譯器編譯)。大型程序邏輯將是非常復雜的,看來還是不要升級編譯器進行編譯的好,因為這將導致dll依賴關系的變化,這真是個無奈的選擇

 

混合編譯選項 /clr看來要考慮允許靜態鏈接運行庫了(現在的VC版本只能動態鏈接運行庫的),因為運行庫DLL存在版本和效率缺陷

 

大家有沒有發現LINUX操作系統下的so文件一般比windows下的要大很多,其中一個原因是這個模型相當于默認全部導出,即使是全局函數也是一樣,哪怕你臨時寫一個沒意義的函數,忘記去掉了,也一并導出,雖然你并沒有給外界頭文件,告訴這個接口如何被調用,但是這個接口已經事實存在了。雖然這樣會簡化一些工作,但是個人覺得,是非常不負責任的,特別是現代的應用大都是多任務模塊化的,這樣做潛在地多吃掉不少內存和硬盤,而且對于版本兼容性,將帶來麻煩。我對LINUX了解不多,不知道是否有支持指定導出函數的方法呢?

COM(Component Object Model), 也許有很多其它弊端,但卻解決了上述問題,而且可以拿掉DLL文件名中描述版本的丑陋數字

 

個人認為,發展C++的二進制接口標準ABI(Application Binary Interface)是非常重要的,COM應該算一個ABI標準吧。總是靜態地依賴源代碼作為可重用模塊,真的弊端很大,多任務時占用的磁盤和內存也會增加。托管編程模型毫無疑問解決了這個問題,當然也帶來了其它方面的一些問題。C++在編程模型上可以說比托管編程模型要簡單很多,但缺少一個二進制標準。解決這個問題將比在語言層面增加幾個關鍵字要重要很多

posted on 2011-08-01 23:54 魏兵 閱讀(3705) 評論(13)  編輯 收藏 引用

Feedback

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-02 02:35 fklz

暈死,顯然是你傻逼不會用!真沒見過這么傻逼還自作聰明的  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-02 14:47 Enic

樓上非常正確,,,  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-02 16:24 樂購網

來好好的學習一下。  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-02 18:46 空明流轉

你用啥沒危害。。。  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-02 19:44 bennycen

看成了“人類的嚴重危害”  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害”[未登錄] 2011-08-03 09:19 劍孤寒

首先,內聯函數全部失效并不是導出類的錯,而是用的人的錯,如果你要內聯就不應該用導出類
其次,私有函數導出并不會顯著增加dll體積,如果dll體積很重要也是有辦法回避這個問題的,另外,私有函數導不導出跟維護沒啥關系吧,都是你內部用的,你不用導出類內部函數出問題還不是也要維護
最后,靜態鏈接庫如果用了stl也是依賴crt的  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-03 10:09 cr

不是這么用的。  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-03 10:48 terminator

傻逼成這樣居然還能長篇大論?夠寒磣人的。  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害”[未登錄] 2011-08-03 19:54 cexer

那些出口就罵人的,都是些畜牲嗎?你爹媽沒教過你怎么說人話?  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害”[未登錄] 2011-08-04 04:37 cexer

搞笑啊,樓上你冒用ID很光彩?看來被人罵傻逼沒罵錯  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害”[未登錄] 2011-08-04 09:11 a

人家理解的不對,大家指出問題、提供解決辦法就行,何必罵人呢?罵完了對你有什么好處啊。朋友多了路好走。樹個敵人對自己有益處?年輕人怎么這么多火焰呢?這么有活力,還不如去改造這個社會做貢獻呢。在團隊方面來講,罵人首先就沒有團隊精神,不合作啊。  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-05 13:07 欲三更

1.按照lz的邏輯,F22戰機的嚴重危害是它們太費油——你都使用導出類了,還在乎什么內聯函數?

2.stl代碼里面什么時候有導出類的符號了?VC的crt說的是C庫。

3.這個時候,進程中的內存結構產生了微妙的變化……以我的經驗,任何一個頭腦正常的工程師都不會做這樣的事情!

4.現在談COM之類的東西,我怎么感覺這是5年前的文章?  回復  更多評論   

# re: 隨想Visual C++ “導出/導入類的嚴重危害” 2011-08-05 20:00 fly C++

@劍孤寒
這個問題我深入考察過MFC動態庫與CRT動態庫的不同,發現MFC頭文件中的內聯成員函數是有效的(這可以通過簡單修改頭文件中的定義代碼,看運行時的效果可以證明,你修改的代碼產生作用,就說明并沒有用到DLL內部的定義),其原因是MFC的頭文件并沒有使用戶通過__declspec(dllimport) class 的方式使用,但是CRT動態庫,卻是隱含的讓使用者采用這種方式,其結果是,當用戶動態鏈接CRT時,其非模板類內聯成員函數(模板類不能真正導出定義),實際上都不可能作為內聯函數了,因為使用的都是DLL內部的定義代碼(這也可以通過上面的方法發現),這將一定程度上影響程序執行效率,并使CRT導出接口龐大(內聯函數導出沒有意義,因為暴露的頭文件已經有定義代碼了,為什么還要使用DLL的定義體呢,而且會傷害運行效率)。我碰到過一個程序,靜態鏈接CRT比動態鏈接CRT要快非常多,并不是程序加載DLL產生的時間延遲,而是程序運行起來之后產生的問題,花了非常多的時間,才確定是這個原因。如果大家有興趣,我可以貼出一段代碼

關于接口維護, 對于C語言寫的DLL, 只是導出一部分外界需要用到的函數,如果C++導出了所有內部定義的東西,不管外界是否要用到,而且私有成員函數對于外界也不可能用到,多少感覺有些那個

以上謹代表個人觀點的  回復  更多評論   



只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


My Links

Blog Stats

常用鏈接

留言簿

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲精品免费一二三区| 一本色道久久88综合亚洲精品ⅰ | 欧美在线观看视频一区二区| 9久草视频在线视频精品| 欧美日韩国产bt| 亚洲一区二区免费视频| 一区二区三区高清在线 | 久久午夜av| 亚洲成人在线网站| 亚洲欧洲日韩综合二区| 欧美日韩在线观看视频| 亚欧美中日韩视频| 久久久一二三| aa日韩免费精品视频一| 亚洲综合色丁香婷婷六月图片| 国产精品美女在线| 久久综合九色| 欧美日韩国产精品一区| 欧美中文字幕视频在线观看| 久久亚洲影音av资源网| 一区二区激情视频| 欧美中文字幕在线视频| 一本久久综合亚洲鲁鲁| 性欧美8khd高清极品| 亚洲欧洲一区二区天堂久久 | 亚洲人成网站777色婷婷| 欧美亚一区二区| 免费成人高清在线视频| 欧美午夜欧美| 欧美jizz19性欧美| 国产精品国产三级国产a| 久久全球大尺度高清视频| 欧美精品一区二区三区久久久竹菊| 午夜精品免费在线| 麻豆成人小视频| 久久av红桃一区二区小说| 欧美成人嫩草网站| 久久久一区二区| 国产精品久久久亚洲一区| 亚洲第一福利社区| 韩国一区二区三区美女美女秀| 99riav久久精品riav| 亚洲国产成人精品视频| 欧美在线一级视频| 亚洲免费在线播放| 欧美日韩国产精品专区| 欧美电影免费观看高清完整版| 国产婷婷色一区二区三区在线| 日韩视频一区二区三区在线播放| 极品av少妇一区二区| 亚洲综合成人在线| 一区二区三区日韩精品视频| 免费在线亚洲| 蜜桃视频一区| 黑人极品videos精品欧美裸| 亚洲欧美美女| 久久国产精品99精品国产| 欧美肉体xxxx裸体137大胆| 亚洲第一页中文字幕| 亚洲国产欧美精品| 麻豆精品在线视频| 久久这里只有精品视频首页| 国产欧美日韩三区| 亚洲尤物在线| 欧美在线观看视频一区二区三区| 国产精品视频不卡| 亚洲一区二区欧美| 欧美制服第一页| 国产欧美一区二区三区视频| 亚洲欧美日韩综合国产aⅴ| 香蕉久久一区二区不卡无毒影院| 国产精品igao视频网网址不卡日韩| 亚洲精品一区二区网址| 一区二区三区欧美在线| 欧美午夜片在线免费观看| 亚洲私人影院| 欧美在线视频观看免费网站| 国产专区欧美精品| 久久亚洲风情| 亚洲三级免费| 先锋影院在线亚洲| 国产一区欧美| 蜜臀av国产精品久久久久| 亚洲国产老妈| 亚洲男人第一av网站| 国产欧美日韩一区二区三区在线 | 模特精品在线| 亚洲精品久久久久中文字幕欢迎你 | 国产精品久久久久久久浪潮网站| 亚洲欧美国产精品va在线观看| 久久精品99国产精品日本| 影音先锋另类| 欧美日精品一区视频| 午夜视频一区在线观看| 欧美刺激性大交免费视频| 国产精品99久久久久久人 | 欧美成ee人免费视频| 亚洲精品激情| 久久精品观看| 夜夜嗨av一区二区三区四区| 国产精品手机视频| 欧美成人dvd在线视频| 亚洲视频在线观看三级| 久久久久久久久久久久久久一区| 亚洲黄色尤物视频| 国产精品久久久久秋霞鲁丝 | 亚洲人午夜精品| 午夜精品久久久久久99热| 亚洲成在人线av| 国产精品久久久一区二区| 美女国产精品| 午夜在线一区二区| 亚洲精品三级| 欧美bbbxxxxx| 久久成人精品一区二区三区| 亚洲精品在线观| 一区二区三区无毛| 国产精品中文在线| 欧美日韩国产成人在线91| 久久久xxx| 午夜在线精品偷拍| 一区二区三区毛片| 亚洲人午夜精品免费| 久久一综合视频| 久久精品二区三区| 午夜精品福利视频| 一区二区三区.www| 亚洲精品自在在线观看| 亚洲国产精品久久久久婷婷老年| 国产精品一卡二| 国产精品乱码| 欧美性猛交99久久久久99按摩| 欧美ab在线视频| 蜜臀av一级做a爰片久久| 久久久国际精品| 欧美一区二视频| 亚洲午夜一区二区三区| 亚洲最新视频在线播放| 亚洲毛片在线免费观看| 亚洲国产一区二区三区高清| 欧美韩日一区| 欧美激情第10页| 亚洲国产va精品久久久不卡综合| 麻豆91精品91久久久的内涵| 久久久亚洲国产天美传媒修理工| 欧美一级播放| 久久久久久有精品国产| 久久久久久69| 乱码第一页成人| 欧美国产成人精品| 亚洲欧洲精品一区二区三区波多野1战4| 欧美大片91| 亚洲欧洲日韩女同| 一区二区三区产品免费精品久久75| 亚洲人成网站精品片在线观看| 亚洲精品免费一二三区| 日韩一级免费观看| 亚洲一区二区三区高清| 午夜视频一区二区| 久久综合伊人77777| 欧美高清视频在线| 国产精品高潮呻吟| 国产亚洲欧美一区在线观看| 激情久久久久久久| av成人免费在线观看| 午夜久久99| 老司机午夜精品| 亚洲精品免费在线观看| 亚洲男人av电影| 久久久亚洲欧洲日产国码αv| 欧美成人蜜桃| 欧美午夜精品久久久久久久| 国产精品日韩精品欧美在线| 一区一区视频| 在线视频欧美精品| 久久精品72免费观看| 亚洲第一精品电影| 亚洲午夜激情免费视频| 久久精品99国产精品日本| 欧美理论电影在线播放| 国产精品黄色在线观看| 一区二区三区无毛| 亚洲午夜av电影| 免费不卡欧美自拍视频| 亚洲私人影院在线观看| 久久一区二区三区四区| 国产精品高潮呻吟| 亚洲欧洲一二三| 久久久99免费视频| 一本色道久久加勒比精品| 久久一区二区三区四区| 欧美性事免费在线观看| 亚洲国产成人av| 久久不射网站| 亚洲视频一二| 欧美激情五月| 亚洲韩国日本中文字幕| 久久国产精品一区二区三区四区| 91久久久久| 久久亚洲综合网|