当前位置: 首页 > news >正文

.NET CLR Hosting 简介

某些軟體(例如 Microsoft SQL Server 2005、Borland JBuilder)需要支援 .NET 或 Java,這樣的軟體可以讓 .NET CLR 或 Java VM 寄宿在自己身上,成為自己的一部份,被 CLR/JVM 所寄宿的軟體就稱為 CLR Host(宿主)或 JVM Host。本文章簡單地介紹 .NET CLR Hosting 的觀念。

本文章內容分成三部分,首先介紹 Shim 和 CLR 的關係,接著說明 CLR Host,最後介紹 .NET Framework CLR 2.0 版的 11 個 Hosting Manager。

Shim and VMs

當你執行 Java 程式時,所使用的 java.exe 與 javaw.exe(Windows版),以及當你執行 .NET 程式時,PE 檔 Import Table 內的『mscoree.dll』,其實都不是真正的 VM,它們只是體積很小的一個入口(Portal)程式(mscoree.dll 只有不到 200KB,java.exe 與 javaw.exe 只有不到 50KB),用來將程式導引到真正的 VM 中,這種入口程式被稱為 Shim(填隙物)。不管是 Java 或 .NET,我們都可以透過 Shim 來決定要使用的VM是哪一種 Build Type:Server 或 Client。Server 版的VM針對 Server 類型的程式做最佳化(高產出),Client 版的VM針對 Client 類型的程式做最佳化(高互動)。如果是 .NET,我們甚至可以透過 Shim 來決定要使用 VM 版本號碼(但是這一點 Java 做不到,因為每個版本的 JVM 都有專屬的 Shim,彼此不太相容。)

如果你的系統上安裝了許多套不同版本號碼的 .NET,那麼程式執行時,Shim 會根據預設值或使用者的指定,來決定要使用的版本和 Build Type 為何(請看圖 1)。.NET CLR 的每個版本都附上兩個 Build Type 的 VM,一個是 MsCorWks.DLL(Wks = Workstation),適合用來執行 Client 端的 .NET 程式,另一個是 MsCorSvr.DLL(Svr = Server),適合用來執行 Server 端的 .NET 程式。不管你裝了幾個版本的 .NET Framework,MsCorEE.DLL 只會有一份,放在 C:\Windows\System32 目錄下。而真正的 CLR(VM)是放在 C:\Windows\microsoft.net\framework\v…\ 目錄下的 MsCorWks.DLL 以及 MsCorSvr.DLL。

對 1
圖 1

以往 J2SE 同時會附上 Server 和 Client 的 JVM(更早的 JVM 還會多附上 Classic JVM),但是 Java 5.0 以後,J2SE 只附上 Client 的 JVM(jre\bin\client\jvm.dll),沒有附上 Server 的 JVM(jre\bin\server\jvm.dll)。想要具有 Server 的 JVM,必須安裝 J2EE 才行。

Java 程式的執行方式是,先由 OS 載入 Shim 來執行,Shim 會請 OS 動態載入 JVM,然後程式的控制權就交到 JVM 手上,再由 JVM 來載入並執行 Java Bytecode。如圖 2 所示。

對 2
圖 2

.NET 程式的執行方式是,先由 OS 直接載入 Managed PE,然後 OS 發現這是 Managed PE,於是立刻載入 Shim 來執行,Shim 會請 OS 動態載入 CLR,然後程式的控制權就交到 CLR 手上,CLR 開始執行 Managed PE 內的 Managed Code。如圖 3 所示。

對 3
圖 3

不管是 Java 或 .NET 的方式,都可以改用 Host 程式作為開始,然後再進入整個流程,如圖 4 所示。(但如果是 Java,則圖 4 中的 Shim 必須刪除,而是 Host 之後直接就是 JVM。)

對 4
圖 4

CLR Host

某些軟體需要支援 .NET 或 Java,這樣的軟體可以讓 .NET CLR 或 Java VM 寄宿在自己身上,這樣的軟體就稱為 CLR Host(宿主)或 JVM Host(如圖 4 所示)。想要成為 Host,就要使用 Hosting API。微軟的 .NET CLR 的 Hosting API 就稱為 CLR Hosting API,而 Java VM 的 Hosting API 則稱為 Java Invocation API。 對於 CLR Hosting API 和 Java Invocation API 來說,兩者比較明顯的差別在於:CLR Hosting 是 COM 介面(但仍有少數幾個獨立的 function),而 Java Native Interface Invocation API 則是 C function 介面。

Microsoft .NET CLR 從 1.0 版就開始支援 CLR Hosting API。為了要支援 SQL Server 2005 的許多功能,在 .NET 2.0 的 CLR 中所支援的 Hosting API 就更完整了。Host 程式就像是在 OS 和 CLR 之間,插入一層,請見圖 5。藉由 .NET 2.0 的 CLR Hosting API,除了不能控制 JIT 之外,你幾乎可以控制 CLR 的一切。從某種角度來看,這也算是一種 API Hook。(但不像 OS API Hook 那麼低階且功能強大。)

對 5
圖 5

如何寫出一個 CLR Host 程式?請看下面的四個步驟。

  1. 實踐 IHostControl 介面。

    你必須設計一個類別,來實踐(implement)IHostControl 介面,如圖 6 所示。此 COM 介面有一個很重要的 function,名為 GetHostManager()。CLR 會呼叫這個 function 來得知你實踐了哪幾個 Hosting Manager,並取得該 Hosting Manager。稍後解釋什麼是 Hosting Manager。

    對 6
    圖 6

    程式如下:

    複製

    class MyHostControl : public IHostControl {
    public:
    HRESULT __stdcall GetHostManager(
    REFIID riid,
    void **ppObject);
    };

    HRESULT __stdcall MyHostControl::GetHostManager(
    REFIID riid,
    void **ppObject) {
    if (riid == IID_IHostMemoryManager) {

    MyHostMemoryManager *pMemMgr =
    new MyHostMemoryManager();
    *ppObject = (IHostMemoryManager *)pMemMgr;
    return S_OK;
    } else if (riid == IID_IHostAssemblyManager) {
    // 類似上面的作法
    }
    *ppObject = NULL;
    return E_NOINTERFACE; // 找不到該Manager
    }


    Host Control 的用途只是用來讓 CLR 取得 Manager,一旦 CLR 取得 Manager 之後,Host Control 也就不再有用了。

  2. 取得 ICLRRuntimeHost

    在 CLR Host 程式中,呼叫 MsCorEE.DLL 內的 CorBindToRuntimeEx(),取得 ICLRRuntimeHost。如下面的程式所示:

    複製
                                ICLRRuntimeHost *pCLR = NULL;
    HRESULT hr = CorBindToRuntimeEx(
    L"v2.0.40103", //選擇版本為2.0.40103
    L"wks", // 選擇Build Type為Client
    STARTUP_CONCURRENT_GC,
    CLSID_CLRRuntimeHost,
    IID_ICLRRuntimeHost,
    (PVOID*) &pCLR;);



  3. 實體化一個 Host Control

    複製
    MyHostControl *pHostControl = new MyHostControl();



  4. 註冊此 Host Control

    利用 ICLRRuntime 介面的 SetHostControl(),來將上面設計好的 MyHostControl 設定進入 CLR 中。程式如下:

    複製
    pCLR->SetHostControl((IHostControl *)pHostControl);



CLR Hosting Managers

.NET Framework CLR 2.0 版有 11 個 Hosting Manager。Host Protection Manager 與 Debugging Manager 完全由 CLR 實踐(表 1 中紅色的部分),Thread Pool Manager 完全由 CLR Host 實踐(表 1 中綠色的部分),其他的 Manager 則完全由 CLR 與 Host 兩者共同實現(表 1 中黃色的部分)。由 CLR 所實踐的介面,一律以 ICLR 做為介面名稱的開頭。由 Host 所實踐的介面,一律以 IHost 做為介面名稱的開頭(有一個例外是:IActionOnCLREvent)。表格 1 整理了所有的 Manager 和介面。

表1
CLR Hosting
Managers
HostCLR
Assembly
Loading
Manager
IHostAssemblyManager
IHostAssemblyStore
ICLRAssemblyReferenceList
ICLRAssemblyIdentityManager
Host Protection
Manager
 ICLRHostProtectionManager
Failure Policy
Manager
IHostPolicyManagerICLRPolicyManager
Memory
Manager
IHostMemoryManager
IHostMalloc
ICLRMemoryNotificationCallback
Garbage
Collection
Manager
IHostGCManagerICLRGCManager
Threading
Manager
IHostTaskManager
IHostTask
ICLRTaskManager
ICLRTask
Thread Pool
Manager
IHostThreadPoolManager 
Synchronization
Manager
IHostSyncManager
IHostCriticalSection
IHostManualEvent
IHostAutoEvent
IHostSemaphore
ICLRSyncManager
I/O Completion
Manager
IHostIoCompletionManagerICLRIoCompletionManager
Debugging
Manager
 ICLRDebugManager
CLR event
Manager
IActionOnCLREventICLROnEventManager

大部分的 Manager 都擁有超過一個的介面,每個 Manager 都有一個介面是 Primary Interface(表 1 中採用粗體字者)。所謂的 Primary Interface,是讓系統用來發現 Host 有沒有提供某個 Manager。如果 Manager 完全由 CLR 與 Host 兩者共同實踐,那麼 primary Interface 是在 Host。如果你決定實踐某個管理員,那麼你必須同時實踐該 Manager 全部的介面。

ICLRRuntime 介面有兩個 function,GetCLRControl() 以及 GetHostControl(),可以用來取得 ICLRControl 以及 IHostControl,利用這兩個介面,可以取得許多的 Manager,如圖 7 所示。

對 7
圖 7

下面簡單地介紹各種 Hosting Manager 的用途。

Assembly Loading Manager

CLR 有定義一套預定的(default)組件載入機制(圖 x)。有一些特殊的應用需要採用自己的組件載入機制,這時候就可以利用 CLR 的 Assembly Loading Manager,來詳細地控制這一切。

Host Protection Manager

讓 CLR 可以對於 Managed Code 進行某些限制。

Failure Policy Manager

讓 Host可以控制,程式出現錯誤時的處置方式。

Memory Manager

讓 Host 可以提供許多記憶體處理相關的 function(例如:VirtualAlloc()),來取代 Win32 版本的 API。如此一來,Host 可以針對記憶體資源做更詳細的安排。

Garbage Collection Manager

讓 Host 可以強迫 CLR 進行 GC 的動作、取得 GC 的統計資料…等。

Threading Manager

將 Thread 變成 Task,並進行自己的排程(Scheduling)方式。此處所謂的 Task,並不是 process 的意思,而是一種程式的執行單位,可以是 Preemptive 的 Thread(由 OS 負責排程),也可以 Non-Preemptive(Cooperative)的 Fiber(由 Host 自行排程)。

Synchronization Manager

讓 Host 自行提供同步化物件(例如:semaphore、event),而不用 OS 所所提供的同步化物件。

Thread Pool Manager

CLR Host 可以提供自己的 Thread Pool、控制 Thread Pool 內的 Thread 個數。

I/O Completion Manager

對於非同步的(Asynchronous)IO,當動作完成時,就會通知 CLR Host 所提供的 Callback function,讓 CLR Host 可以進一步處理。

Debugging Manager

利用 Debugging Manager,可以控制 debugger 的行為。例如,載入額外的程式資訊檔案。

CLR Event Manager

當 managed code 在執行時,遇到某些特定的事件,就會通知 CLR Host 所提供的 Callback function,讓 CLR Host 可以進一步處理。

利用 CLR Hosting 來支援 .NET 的軟體會越來越多

以前大家會用專屬的技術(特別是 Scripting 語言)來讓自己的軟體系統可以被擴充,以後這樣的狀況勢必會漸漸減少,而是漸漸改用 .NET 的 Managed Code,如此一來,就可以採用各種語言,且功能更完備,耗費的心力更少。這些軟體都需要利用 CLR Hosting 的技術。

隨著 .NET 2.0 的擴充性提高,使用 .NET CLR Hosting 的程式將會越來越多。事實上,目前已經有一些重要的軟體開始運用 CLR Hosting,來讓 managed code 可以在自己的系統中執行,這些軟體包括了 SQL Server 2005、IIS、IE、IBM DB2、AutoDesk AutoCAD。


原文URL:http://msdn.microsoft.com/zh-tw/library/dd229217.aspx

转载于:https://www.cnblogs.com/jeriffe/articles/1962175.html

相关文章:

  • 2017,智能音箱究竟何去何从?
  • 大学笔记
  • 二叉树中的和为某一值的路径
  • css 背景属性详细总结
  • 使用Aspose.Cell控件实现Excel高难度报表的生成(二)
  • 第十四章 重载运算与类型转换
  • 使用类的思想来重构asp网站开发
  • android129 zhihuibeijing 聊天机器人
  • 【转】nios II架构uclinux的过程
  • 开发人员学Linux(4):使用JMeter对网站和数据库进行压力测试
  • 项目选题报告
  • [转载]精益求精Sybase数据库标题大包括-6
  • Android基础:SQLites数据库事物处理的优越性
  • DB2 9 利用斥地(733 测验)认证指南,第 9 部分: 用户定义的例程(2)
  • JS区别IE6、IE7、IE8之间的方法
  • [译]前端离线指南(上)
  • 【node学习】协程
  • echarts的各种常用效果展示
  • Java比较器对数组,集合排序
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • pdf文件如何在线转换为jpg图片
  • Python实现BT种子转化为磁力链接【实战】
  • rc-form之最单纯情况
  • react-native 安卓真机环境搭建
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 反思总结然后整装待发
  • 马上搞懂 GeoJSON
  • 前端之Sass/Scss实战笔记
  • 如何解决微信端直接跳WAP端
  • 网页视频流m3u8/ts视频下载
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 找一份好的前端工作,起点很重要
  • postgresql行列转换函数
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • # C++之functional库用法整理
  • (动态规划)5. 最长回文子串 java解决
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (九)One-Wire总线-DS18B20
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (转)Oracle存储过程编写经验和优化措施
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • @angular/cli项目构建--Dynamic.Form
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [1181]linux两台服务器之间传输文件和文件夹
  • [BUUCTF 2018]Online Tool
  • [C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项
  • [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子
  • [GN] DP学习笔记板子
  • [HOW TO]怎么在iPhone程序中实现可多选可搜索按字母排序的联系人选择器
  • [IMX6DL] CPU频率调节模式以及降频方法