2010-02-13 60 views
2

我有一個編譯器,目標.NET運行時(CLR)。編譯器的當前版本是用標準C++編寫的(非託管的)。編譯器目前缺乏對編譯時引用程序集的支持,所以我「導入」.NET庫的方式是使用.NET編寫的實用程序存根生成器,該生成器反映了任何程序集並在我的自定義語言中爲它發出簽名存根。我預先爲我使用的所有.NET程序集生成存根。在編譯時,我的編譯器編譯存根文件以填充符號表等,以便它可以從.NET API解析類型和方法。這是我的「使用」版本。但這是暫時的,現在我想向編譯器添加一個實際的「使用」或「導入」指令。我需要在編譯時訪問引用程序集中的元數據/類型信息。.NET編譯器 - CLR程序集元數據訪問/從非託管C++反射

我的問題:我需要關於如何從非託管C++訪問CLR程序集元數據的建議。或者,我需要將其轉換爲託管C++應用程序並使用.NET反射支持。純C++的目的是,我也可以在Linux上編譯Mono,此外,除CLR之外,我還有另一個運行時的部分後端。

+0

可能重複:http://stackoverflow.com/questions/2216551/loading-managed-dll-into-appdomain-from-native-c-代碼/ 2217034 – 2010-02-13 02:23:41

+0

爲什麼不在編譯器中創建一個迷你加載器來加載.NET運行時宿主環境並加載自定義的.NET例程來爲您進行反射並獲取簽名存根......? – t0mm13b 2010-02-13 02:23:46

+0

@Moron:當我輸入以前的評論時,你說出了我的想法? – t0mm13b 2010-02-13 02:24:24

回答

3

我認爲這是由CoCreateObject()CLSID_CorMetaDataDispenser coclass完成的,要求提供IID_IMetaDataDispenser接口。 IMetaDataDispenser :: OpenScope()讓你打開程序集的元數據。請求IID_IMetaDataAssemblyImport,它有一堆迭代元數據的方法。

小心.NET 4.0,它即將來臨,我很確定元數據格式已經改變。儘管這應該只是生成元數據的一個問題,但只要獲得接口的4.0版本,閱讀應該是向後兼容的。 <cor.h>具有特定於版本的元數據協作者的CLSID。

我會假設你不感興趣的Irony.

+0

謝謝,這是我正在尋找(非託管API)的線。 – codenheim 2010-02-13 15:18:18

1

這是從MSDN文章「CLR內向外:CLR託管的API」,2006年8月

 
int main(int argc, _TCHAR* argv[]) 
{ 
    // Bind to the runtime. 
    ICLRRuntimeHost *pClrHost = NULL; 
    HRESULT hrCorBind = CorBindToRuntimeEx(
     NULL, // Load the latest CLR version available 
     L"wks", // Workstation GC ("wks" or "svr" overrides) 
     0,  // No flags needed 
     CLSID_CLRRuntimeHost, 
     IID_ICLRRuntimeHost, 
     (PVOID*)&pClrHost); 

    // Construct our host control object. 
    DHHostControl *pHostControl = new DHHostControl(pClrHost); 

    // Notify the CLR that this host implements hosting managers. 
    pClrHost->SetHostControl(pHostControl); 

    // Now, start the CLR. 
    HRESULT hrStart = pClrHost->Start(); 

    // Load an assembly and execute a method in it. 
    HRESULT hrExecute = pClrHost->ExecuteInDefaultAppDomain(
     pwzAssemblyPath, pwzAssemblyName, 
     pwzMethodName, pwzMethodArgs, 
     &retVal); 
} 

還有另一個MSDN「高級技術避免和檢測死鎖在.NET應用程序」,四月,2006年的一篇關於'通過宿主API探索'的部分,這也有助於解釋如何使用API​​從C/C++代碼託管。

希望這會有所幫助, 最好的問候, 湯姆。

+0

@Tom:感謝您的建議。但是我的主要目標(約束)根本不依賴於CLR。如果我決定託管CLR,那麼調用外部存根生成器並動態解析文本輸出實際上並不複雜。所以我不打折你的答案,但我正在尋找一種讓編譯器在沒有.NET運行時的情況下運行的方式。另外,請考慮,我希望這個最終仍然可以在Linux上編譯。我確信有人會問「在不依賴於CLR的情況下,CLR的目標是什麼」。我自己並沒有想到,但請幽默我。 – codenheim 2010-02-13 04:11:53

+0

也許用於讀取.NET程序集元數據的C++庫?我記得在幾年前的一次研究中,除了Mono工具包之外,沒有發現任何東西。 – codenheim 2010-02-13 04:14:05