.NET Framework 2.0 組件和非托管代碼與交互操作詳解(轉)

?????.NET Framework 將促進與 COM 組件、COM+ 服務、外部類型庫和許多操作系統服務的交互操作。在托管和非托管對象模型之間,數據類型、方法簽名和錯誤處理機制都存在差異。為了簡化 .NET Framework 組件和非托管代碼之間的互用并便于進行移植,公共語言運行時將從客戶端和服務器中隱藏這兩種對象模型之間的差異。

??????在運行時控制下執行的代碼稱作托管代碼。相反,在運行時之外運行的代碼稱作非托管代碼。COM 組件、ActiveX 接口和 Win32 API 函數都是非托管代碼的示例。

  與非托管代碼交互操作

NET Framework比其他開發平臺多提供了很多先進技術, 然而, 很少公司能承受起重新設計和重新實現所有的代碼. 微軟意識到這點, 因此構建了CLR來提供一種機制允許應用程序可以包含托管代碼和非托管的代碼. 特別地, CLR支持三種交互場景:

?? 托管代碼可以調用DLL中的非托管的函數: 托管代碼可以很容易地調喲哦能夠包含在DLL中的函數, 這是通過使用一種稱為P/Invoke (Platform Invoke) 的機制來實現的. 畢竟, 定義在FCL中的很多類型都內部調用了Kernel32.dll, User32.dll等中的函數. 很多編程語言將暴露一種機制使得托管代碼很容易調用包含在DLL中的非托管函數. 例如, 一個C#應用程序可以調用Kernel32.dll中的CreateSemaphore函數.

?? 托管代碼可以使用COM組件(server): 很多公司已經實現了很多非托管的COM組件, 使用這些組件中的類型, 可以創建用于描述COM組件的托管的程序集, 托管的代碼可以訪問這些程序集中的托管的類型, 這就和訪問其他托管類型一樣. 參考與.NET Framework SDK一起發布的Tlbimp.exe工具. 有時候, 你可能沒有一個類型庫或者你想對TlbImp.exe產生的東西獲得更多的控制, 這樣, 你可以手動地構建一個類型, 讓CLR可以使用這個類型來實現適當的互操作. 例如, 你可以在C#應用程序中使用DirectX COM組件.

?? 非托管的代碼可以使用托管的類型(server): 很多現有的非托管的代碼需要你提供COM組件才能讓代碼正常地工作. 很容易通過托管代碼來實現這些組件, 這樣你可避免代碼必須處理引用計數和接口. 例如, 你可以用C#創建一個ActiveX控件或者shell extension. 參考TlbExp.exe和RegAsm.exe工具.

????
??????除了這些場景, 微軟的C++/CLI編譯器(version 14)支持一個新的/clr命令行開關, 這個開關告訴編譯器產生IL代碼, 而不是native CPU指令. 如果你有大量已有的C++代碼, 你可以使用這個新編譯開關重新編譯這些代碼, 新的代碼需要CLR才能執行, 你可以修改代碼來充分利用CLR特有的功能.

但是對于下面的方法, /clr開關目前還不能將它們編譯成IL代碼: 包含內聯匯編語言(通過關鍵字__asm實現); 接受可變數目參數的方法; 調用setjmp的方法; 包含一些內部程序(intrinsic routine)(例如__enable, __disable, __ReturnAddress, __AddressOfReturnAddress)的方法. 對于C++/CLI編譯器不能編譯成IL的完整列表, 可以參考關于編譯器的文檔. 當編譯器不能編譯成IL時, 它會將方法編譯成x86代碼, 使得應用程序仍然能運行.

記住盡管產生的IL代碼是托管的, 但是數據并不是, 也就是說數據對象不是從托管堆上分配的, 因此它們不能使用垃圾回收機制. 實際上, 數據類型沒有包含在metadata中, 并且這些類型的方法名仍然需要經過C++簽名編碼中轉換(mangle).

下面的C代碼調用了標準C運行時庫函數printf, 也調用了System.Console.WriteLine方法, System.Console類型定義在FCL中, 因此C/C++代碼可以使用.

#include <stdio.h> // For printf

#using <mscorlib.dll> // For managed types defined in this assembly

using namespace System; // Easily access System namespace types

// Implement a normal C/C++ main function

void main() {

// Call the C runtime library's printf function.

printf("Displayed by printf.\r\n");

// Call the FCL's System.Console's WriteLine method.

Console::WriteLine("Displayed by Console::WriteLine.");

}

編譯這段代碼不是很容易, 如果這個代碼是在文件ManagedCApp.cpp中, 你會執行如下的命令來編譯它:

cl /clr ManagedCApp.cpp

結果是ManagedCApp.exe程序集文件, 如果你運行ManagedCApp.exe, 你將會看到如下的輸出:

C:\>ManagedCApp

Displayed by printf.

Displayed by Console::WriteLine.

如果你使用ILDasm.exe來檢查這個文件, 你將會看到定義在這個程序集中的所有的全局函數和全局字段, 顯然地, 編譯器自動地產生了很多填充代碼. 如果你雙機Main函數, ILDasm會為你顯示出IL代碼.

.method assembly static int32

modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) main() cil managed

{

? .vtentry 70 : 1

? // Code size 23 (0x17)

? .maxstack 1

? IL_0000: ldsflda valuetype '<CppImplementationDetails>' .$ArrayType$$$BY0BH@$$CBD

?????????????????????? modopt([mscorlib]System.Runtime.CompilerServices.IsConst)

?????????????????????? '??_C@_0BH@GBHlFCOF@Displayed?5by?5printf?4?$AN?6?$AA@'

? IL_0005: call???? vararg int32

?????????????????????? modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl)

?????????????????????? printf(

???????????????????????? int8

???????????????????????? modopt(

?????????????????????????? [mscorlib]System.Runtime.CompilerServices.IsSignUnspecifiedByte)

???????????????????????? modopt(

?????????????????????????? [mscorlib]System.Runtime.CompilerServices.IsConst)*

??????????????????????? )

? IL_000a: pop

? IL_000b: ldstr "Displayed by Console::WriteLine"

? IL_0010: call void [mscorlib]System.Console::WriteLine(string)

? IL_0015: ldc.i4.0

? IL_0016: ret

} // end of method 'Global Functions'::main

?

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/libright/archive/2009/03/04/3957359.aspx

?

轉載于:https://www.cnblogs.com/elock/archive/2009/09/02/1558902.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248249.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git 刪除遠程分支和本地分支

刪除遠程分支和本地分支 https://www.cnblogs.com/luosongchao/p/3408365.html 將遠程git倉庫里的指定分支拉取到本地&#xff08;本地不存在的分支&#xff09; https://www.cnblogs.com/hamsterPP/p/6810831.html 轉載于:https://www.cnblogs.com/mafeng/p/10619419.html

從零開始實現ASP.NET Core MVC的插件式開發(四) - 插件安裝

標題&#xff1a;從零開始實現ASP.NET Core MVC的插件式開發(四) - 插件安裝 作者&#xff1a;Lamond Lu 地址&#xff1a;https://www.cnblogs.com/lwqlun/p/11343141.html 源代碼&#xff1a;https://github.com/lamondlu/Mystique 前情回顧 從零開始實現ASP.NET Core MVC的插…

立體導航翻轉案例

<div class"box"><!-- 立方體 --><ul><li><img src"img1/1.jpg" alt""></li><li><img src"img1/2.jpg" alt""></li><li><img src"img1/3.jpg" a…

Uncontrolled memory mapping in camera driver (CVE-2013-2595)

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主同意不得轉載。https://blog.csdn.net/hu3167343/article/details/34434235 /* 本文章由 莫灰灰 編寫&#xff0c;轉載請注明出處。 作者&#xff1a;莫灰灰 郵箱&#xff1a; minzhenfei163.com */ 1漏洞描寫…

表格隔行變色

<body><table border"0" align"center" cellspacing"1" cellpadding"0"><caption>恭喜發財</caption><thead><tr><th>代碼</th><th>名稱</th><th>最新公布凈值<…

啟動Cognos時報0106錯誤

1. 問題描述 啟動Cognos失敗&#xff0c;報錯代碼為0106。 2. 問題分析 是jdk版本不兼容。 3. 解決方案 方案一&#xff1a;更換jdk1.6&#xff0c;可以使用免安裝版&#xff0c;不需要卸載原有的jdk將java_home的路徑替換成jdk1.6的路徑。 方案二&#xff1a;使用Cognos自帶jd…

項目管理的測試版發布

最近有時間將以前沒有寫完的項目管理程序進一步完善&#xff0c;加入了項目任務之間的關連。功能&#xff1a;1、任務的關連Start to finishStart to startFinish to startFinish to finish2、任務關連表環路檢測3、采用MVC模式進行開發4、自動導出XML5、雙擊連接線可以設置、刪…

劍指offer.機器人的運動范圍

地上有一個 m 行和 n 列的方格&#xff0c;橫縱坐標范圍分別是 0~m?1 和 0~~n?1。一個機器人從坐標0,0的格子開始移動&#xff0c;每一次只能向左&#xff0c;右&#xff0c;上&#xff0c;下四個方向移動一格。但是不能進入行坐標和列坐標的數位之和大于 kk 的格子。請問…

Tab欄切換布局分析

<body><div class"tab"><div class"tab_list"><ul><li class"current">商品介紹</li><li>規格與包裝</li><li>售后包裝</li><li>商品評價(50000)</li><li>手機社…

CLR基礎,CLR運行過程,使用dos命令創建、編譯、運行C#文件,查看IL代碼

CLR是Common Language Runtime的縮寫&#xff0c;是.NET程序集或可執行程序運行的一個虛擬環境。CLR用于管理托管代碼&#xff0c;但是它本身是由非托管代碼編寫的&#xff0c;并不是一個包含了托管代碼的程序集&#xff0c;所以不能使用IL DASM進行查看&#xff0c;但CLR以dll…

表單的全選取消全選

<div class"wrap"><table border"1" cellspacing"0" cellpadding"0"><caption>恭喜發財</caption><thead><tr><th><input type"checkbox" id"j_cbAll" checked&quo…

VUE 數據綁定模塊渲染 computed(實現通過路由id 查詢數據json結構,對應的值來放在面包屑中)...

異步請求的值放在vuex中&#xff0c;然后頁面掛載該數據和渲染頁面 computed 計算屬性是基于它的依賴緩存的。計算屬性在它的相關依賴發生改變時會重新取值&#xff0c;所以當ajax請求回來的數據發生變化時&#xff0c;計算屬性的值會進行更新&#xff0c;相關的模板引用也會重…

ThinkJs筆記瑣碎

ThinkJs筆記瑣碎 記錄一些瑣碎的在使用ThinkJs遇到的問題 靜態資源訪問 ThinkJs默認production環境關閉對www下資源的相對路徑的訪問&#xff0c;官方建議通過nginx轉向的地址的絕對路徑訪問&#xff0c;想要在production環境訪問相對路徑的話需要到src/config/middleware.js里…

js(Dom+Bom)第二天(1)

JavaScript-DOM操作 核心知識點 className操作標簽樣式style屬性方式操作標簽樣式操作表單控件 學習目標 能夠通過className方式給標簽設置樣式能夠通過style方式給標簽設置樣式能夠獲取表單控件中的值 操作元素樣式 語法&#xff1a;1.dom.className 類名;2.dom.style.屬…

HDU 4339 Query

算法: 比賽時沒有想到好的算法&#xff0c;暴力是O&#xff08; Q * N &#xff09;肯定超時。 賽后&#xff0c;線段樹&#xff0c;樹狀數組&#xff0c;HASH都能AC&#xff0c;想了下&#xff0c;的確用樹狀數組 時間復雜度就可以優化到O&#xff08;Q * lgN * lgN) 2000msAC…

201904快速閱讀術

在看過了幾本數之后&#xff0c;發現原來培養讀書的習慣好像也不太難&#xff0c;“將讀書融入生活&#xff0c;框定讀書時間” 生活中&#xff0c;我確實也是這樣執行了。利用每天上下班的時間聽書&#xff0c;有些覺得可以讀快的書籍用了1.5倍速度在聽&#xff0c;難懂的部分…

js(Dom+Bom)第二天(2)

webAPI 00-操作圖片 知識點-獲取圖片src屬性 圖片對象.src ----> 獲取圖片路徑注意: 1. 獲取到的圖片路徑是一個絕對路徑知識點-動態的給圖片標簽設置路徑 圖片對象.src 圖片路徑;注意: 1.可以設置絕對路徑(不推薦) 2.可以設置相對路徑課堂案例-切換圖片案例 01-操作標…

javaScript今日總結

javascript簡單介紹ECMAScript 1.語法 2.變量&#xff1a;只能使用var定義&#xff0c;如果在函數的內容使用var定義&#xff0c;那么它是一個局部變量&#xff0c;如果沒有使用var它是一個全局的。弱類型&#xff01; 3.數據類型&#xff1a;原始數據類型(undefined/null/stri…

使用Connector / Python連接MySQL/查詢數據

使用Connector / Python連接MySQL connect()構造函數創建到MySQL服務器的連接并返回一個 MySQLConnection對象 在python中有以下幾種方法可以連接到MySQL數據庫&#xff1a; 1.使用connect&#xff08;&#xff09;構造函數import mysql.connectorcnx mysql.connector.connect…

最簡方式 表格編輯 基于 el-table

共下面5點1.新增一個顯示和隱藏的參數2.在顯示那邊新增一個input框&#xff0c;用v-model綁定數據&#xff0c;用v-if來顯示和隱藏3.給之前的顯示的span標簽添加v-else 和上面形成if else4.編輯和保存按鈕同理&#xff0c;然后編輯按鈕觸發的任務將所有輸入打開。即seen置為tru…