在 Visual Studio
NET
中初始化混合DLLs很麻煩
需要手工干預
但在 Visual Studio
中
Visual C++ 和 CLR 團隊設計了一種新的初始化模型
這種新模型更簡單
更自動化
Visual Studio
NET
的根本問題在於將本地代碼和托管代碼一起置於單
池
中
DllMain 期間該池的運行是不安全的
托管代碼根本就不能在這裡運行
新的模型將靜態初始化匯集在兩個單獨的池中
一個池負責本地的靜態初始化
另一個負責托管代碼的初始化
第一個池在 DllMainCRTStartup 期間進行初始化
就像本地代碼那樣
第二個池的初始化
我們加入了一個新的托管代碼初始化階段
當某個包含托管代碼的模塊被加載到應用程序域(AppDomain)時
CLR 將會在任何托管代碼運行之前運行一個特殊tor 函數(我們把它叫做
模塊構造函數
)
托管C運行時(msvcmrt
lib)包含一個模塊構造函數
由它負責初始化第二個池
同時它還安裝一個應用程序域的 unload 事件來運行托管靜態析構函數和 exit 函數
這種新模型意味著到托管代碼的遷移或添加托管代碼到現有的應用程序將變得更加容易
因為不需要再添加定制的初始化入口點
遷移期間
你可能還會碰到本地代碼調用托管代碼的情況
你的代碼要可靠地啟動和關閉
必須解決這個問題才行
否則會出現 C 運行時庫的R
錯誤
或者在調試器下運行時出現 CLR 警告
為了在 Visual Studio
Beta
或以後的版本中解決這個問題
使用調試器的調用堆棧(call stack)找到此煩人的函數
並將該函數要麼移到某個頭文件中
或者本地原文件中
以便將它編譯成本地代碼
你可能注意到了通過 #pragma managed 解決此類問題的建議
請盡量避免這種做法
用這種方法來解決這個問題非常難以湊效
尤其是在你具備自己的 DllMain 或 RawDllMain 時更是如此
此時必須保證將此函數放在本地代碼集中
如果你采納了保羅描述的解決方案
從 Visual C++
到
的遷移不會有太多麻煩
當你重新編譯時
你會看到關於使用 _vcclrit
h 中函數的不滿警告
此時刪除對該文件的引用並進行手工初始化即可
為了完全恢復使用CRT
你還應該從編譯開關中去掉 /Zl
從鏈接開關中去掉 /NOENTRY
這是 Visual Studio
中大量改動的地方之一
目的是方便將 C++ 應用程序遷移到托管代碼使用環境
使用最新的生成產品
我們已經看到大量應用程序在相當短的時間內轉移到了托管環境中
Visual Studio
Beta
出爐後用用看吧
並把使用情況反饋給我們
From:http://tw.wingwit.com/Article/program/net/201311/13422.html