九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
64位環(huán)境中.net framework的運(yùn)行機(jī)制探討
近在編寫(xiě).net應(yīng)用程序時(shí),發(fā)現(xiàn)某些平臺(tái)下無(wú)法加載SQLite DLL的問(wèn)題。

癥狀表現(xiàn)為:

a. 本地Windows 7/8 64bit開(kāi)發(fā)環(huán)境完全正常。
b. 某些Windows 7 64bit用戶的計(jì)算機(jī)無(wú)法加載System.Data.SQLite.DLL。
c. 極個(gè)別Windows XP的計(jì)算機(jī)無(wú)法加載該DLL。


無(wú)法加載DLL時(shí),均報(bào)BadImageFormatException異常,甚至直接被Windows關(guān)閉而無(wú)法采集異常信息。奇怪的是在當(dāng)前目錄包含了這個(gè)DLL文件,所以理應(yīng)能成功加載才是。

由于各種場(chǎng)景的組合在一起,一時(shí)很難判斷問(wèn)題出于何處。起初筆者努力嘗試各種方法試圖在本機(jī)重現(xiàn),也均告失敗。在偶然的機(jī)會(huì),筆者刪除了本機(jī)所有與SQLite相關(guān)的組件,問(wèn)題成功重現(xiàn)。

絕望之中燃起了一點(diǎn)希望。我發(fā)現(xiàn)自己曾經(jīng)安裝了三個(gè)與SQLite相關(guān)的組件:

Java代碼
 
  1. SQLite-1.0.66.0-setup.exe   
  2. sqlite-netFx35-setup-bundle-x64-2008-1.0.82.0.exe   
  3. sqlite-netFx35-setup-bundle-x86-2008-1.0.82.0.exe  


反復(fù)多次后確認(rèn)了以下內(nèi)容:

Java代碼
 
  1. SQLite-1.0.66.0-setup.exe - 無(wú)效果   
  2. sqlite-netFx35-setup-bundle-x86-2008-1.0.82.0.exe - 無(wú)效果   
  3. sqlite-netFx35-setup-bundle-x64-2008-1.0.82.0.exe - 成功  


看來(lái),用戶系統(tǒng)上沒(méi)有sqlite-netFx35-setup-bundle-x64-2008-1.0.82.0.exe,所以導(dǎo)致運(yùn)行失敗。經(jīng)仔細(xì)檢查,這個(gè)包在系統(tǒng)GAC中安裝了64位DLL,而之前我發(fā)布的目錄中包含的是32位DLL文件。一切真相大白,將64位版本與32位版本分開(kāi)發(fā)布,問(wèn)題解決!

到這里,本該可以松口氣了,但我心中仍然充滿疑惑:

(1) 在64位系統(tǒng)上,我的.net應(yīng)用到底算是32位的還是64位的?

(2) 32位應(yīng)用程序照理可以在64位系統(tǒng)上正常運(yùn)行,為什么當(dāng)前目錄的DLL沒(méi)有加載成功?

(3) 為何以前調(diào)用的第三方DLL從沒(méi)有發(fā)生32/64位的問(wèn)題,只有這個(gè)DLL如此特別?

(4) .net的加載DLL的順序是什么,到底以哪個(gè)優(yōu)先?


經(jīng)過(guò)一番認(rèn)真的Google,上述迷團(tuán)一一破解。

(1) 在64位系統(tǒng)上,.net程序是通常以64位程序運(yùn)行的。Windows不會(huì)啟用Wow。這可以從任務(wù)管理器中看到(在64位系統(tǒng)中運(yùn)行的32位程序?qū)⒁?32或“32位”標(biāo)記)。


然后事情并非還如此簡(jiǎn)單。.net程序目前有以下幾種處理器架構(gòu):

Java代碼
 
  1. Any CPU(處理器無(wú)關(guān)的純MSIL代碼)   
  2. x64(僅64位處理器,又稱AMD64)   
  3. x86(僅32位處理器)   
  4. IA64(僅IA64位處理器)  


之前所說(shuō)的“通?!?,即指Any CPU。這樣的程序在32位系統(tǒng)上以32位模式運(yùn)行,在64位系統(tǒng)上以64位模式運(yùn)行。這時(shí),而標(biāo)識(shí)為特定處理器的,只能在相應(yīng)的模式上運(yùn)行。

更詳細(xì)地,使用corflags工具可以看到以下信息:


Java代碼
 
  1. D:\Lib\x64\>corflags System.Data.SQLite.DLL     
  2. Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42     
  3. Copyright (c) Microsoft Corporation.  All rights reserved.     
  4.      
  5. Version   : v2.0.50727     
  6. CLR Header: 2.5     
  7. PE        : PE32+     
  8. CorFlags  : 24     
  9. ILONLY    : 0     
  10. 32BIT     : 0     
  11. Signed    : 1   


Java代碼
 
  1. D:\Lib\x86\>corflags System.Data.SQLite.DLL     
  2. Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  2.0.50727.42     
  3. Copyright (c) Microsoft Corporation.  All rights reserved.     
  4.      
  5. Version   : v2.0.50727     
  6. CLR Header: 2.5     
  7. PE        : PE32     
  8. CorFlags  : 24     
  9. ILONLY    : 0     
  10. 32BIT     : 0     
  11. Signed    : 1  


ILONLY: 在映像中是否只包含了IL代碼。1表示純IL代碼,0表示包含了Native代碼。
32BIT: 即使是純IL代碼,在32位與64位環(huán)境中運(yùn)行還是有區(qū)別的。這個(gè)標(biāo)記用于區(qū)分x86與Any CPU。
PE: 32位為PE32,64位為PE32+。這個(gè)用于區(qū)分32位與64位映象。


Java代碼
 
  1. Any CPU:PE = PE32  and 32BIT = 0  
  2. x86:    PE = PE32  and 32BIT = 1  
  3. x64:    PE = PE32+ and 32BIT = 0  


由于之前我們?cè)噲D在64位進(jìn)程上加載的32位DLL,其ILONLY=0,即包含平臺(tái)相關(guān)代碼,因此無(wú)法加載而拋出錯(cuò)誤。【注:通過(guò)現(xiàn)象推測(cè),需要跟蹤.net Framework代碼證實(shí)】

(2) 這個(gè)問(wèn)題通過(guò)上述剖析,已經(jīng)很清楚了。要說(shuō)明的是,如果想繞過(guò)64位DLL帶來(lái)的麻煩,將主程序也編譯成x86而不是Any CPU,也是可以在64位系統(tǒng)上運(yùn)行的。這時(shí),操作系統(tǒng)將啟用Wow模式啟動(dòng)這個(gè)進(jìn)程。

(3) 這個(gè)SQLite的DLL混合了IL和Native代碼,必須嚴(yán)格地對(duì)應(yīng)平臺(tái)調(diào)用。

(4) .net加載程序集的順序:

1、 在GAC(Global Assembly Cache)中搜索相應(yīng)版本的DLL;
2、 配置文件(web.config或app.config);
3、 應(yīng)用程序(.exe)當(dāng)前目錄下;

但事實(shí)上有可能比這個(gè)順序更為復(fù)雜,詳見(jiàn):
http://msdn.microsoft.com/en-us/library/aa720133.aspx 及參考文獻(xiàn)7。

之前,在我開(kāi)發(fā)環(huán)境中,由于本地GAC中已經(jīng)包含了正確的x64版本,所以能正確運(yùn)行。但復(fù)制到別人的64位機(jī)器上時(shí)就出問(wèn)題了。而有些XP機(jī)器上安裝了錯(cuò)誤的小版本,因此也出現(xiàn)加載失敗的現(xiàn)象。

最后,補(bǔ)充說(shuō)明一下GAC的位置:\Windows\assembly。使用“我的電腦”打開(kāi)這個(gè)目錄時(shí),看到的是所有.net全局程序集的列表,這是Windows特殊處理后的結(jié)果。只有通過(guò)命令行才能看到這個(gè)目錄中分成了GAC_32, GAC_64, GAC_MSIL等幾個(gè)子目錄。這幾個(gè)目錄正是前文所述不同處理器架構(gòu)的幾種DLL。

補(bǔ)充:
關(guān)于之前[c]的問(wèn)題的解決方案:

后來(lái)發(fā)現(xiàn),System.Data.SQLite.DLL版本1.0.66均能正常工作,但1.0.82在某些Windows XP上無(wú)法工作。由于官方網(wǎng)站對(duì)1.0.82的解釋大多關(guān)注在x86與x64的區(qū)別,我一度仍然以為是處理器架構(gòu)造成的。最后,通過(guò)depends工具查看發(fā)現(xiàn),1.0.82版的DLL引用了MSVCR90.DLL。而出問(wèn)題的機(jī)器上未安裝VC2008 Runtime,自然無(wú)法找到該DLL了。

解決的辦法有兩個(gè):使用1.0.66版,或在XP上安裝VC2008運(yùn)行包:
http://www.microsoft.com/zh-cn/download/details.aspx?id=29

由于之前對(duì)64位平臺(tái)應(yīng)用的理解有限,文中很多內(nèi)容通過(guò)實(shí)驗(yàn)推測(cè),有可能和Microsoft官方表述有不一致或者錯(cuò)誤的地方。歡迎大家指正!


參考文獻(xiàn):

1、http://msdn.microsoft.com/en-us/magazine/dd727509.aspx
2、http://blogs.msdn.com/b/gauravseth/archive/2006/03/07/545104.aspx
3、http://blogs.msdn.com/b/junfeng/archive/2004/08/11/212555.aspx
4、http://blogs.msdn.com/b/junfeng/archive/2004/09/12/228635.aspx
5、http://blog.csdn.net/cstod/article/details/4887049
6、http://stackoverflow.com/questions/6507675/gac-32bit-vs-64bit
7、http://blog.csdn.net/wangjunhe/article/details/6692194
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
(1)程序集基礎(chǔ)知識(shí)
精簡(jiǎn)版XP+XPT
缺少.net framework 3.5怎么辦?
讓EF飛一會(huì)兒:如何用Entity Framework 6 連接Sqlite數(shù)據(jù)庫(kù)
玩游戲怎能沒(méi)有.NET Framework 3.5,你會(huì)安裝它嗎?
Unable to load sqlite_jni: java.lang.UnsatisfiedLinkError: already loaded in another classloader
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服