託管、非託管、本地:這些代碼有什麼區別?

託管、非託管、本地:這些代碼有什麼區別?
隨着2003年4月24日 VS 2003(之前成爲Everett)發佈,很多開發者願意考慮使用託管代碼的新技術。但是對於C++開發者,這個新技術有點迷茫。因爲,正如我之前指出的,C++是特殊的。
Managed, Unmanaged, Native: What Kind of Code Is This?
Kate Gregory April 28, 2003
With the release of Visual Studio .NET 2003 (formerly known as Everett) on April 24th, many developers are now willing to consider using the new technology known as managed code. But especially for C++ developers, it can be a bit confusing. That's because C++, as I pointed out in my first column here, is special.
本文是針對VS 2003,雖然該文章寫的時間比較早,但是完全可以說明問題。

什麼是託管代碼?

託管代碼是Visual Basic .NET和C#編譯器創建的。它編譯成中間語言(IL),而不是直接在計算機上運行的機器代碼。IL被保存在一個稱爲程序集中,以及描述代碼的類、方法、和屬性(如安全性要求的)的元數據文件。在.NET裏,程序集是“一站式”部署的單元。你可以將程序集直接複製到另一臺服務器上進行部署。託管代碼運行在公共語言運行庫。運行時爲你正在運行的代碼提供多種服務。在通常代碼事件中,它首先加載和驗證程序集,確保IL正確。然後,當程序集運行、方法被調用時,運行時安排它們被編譯爲適合機器的機器碼,並緩存該機器碼,以便下次被調用時使用。這被稱爲 Just In Time,或 JIT compiling,或簡稱 Jitting。
當程序集運行時,運行時繼續提供諸如安全、內存管理、線程和其他的服務。應用程序是由運行時來管理的。Visual Basic .NET 和 C# 只能產生託管代碼。如果你用的是這些應用程序,那麼你就正在使用託管代碼。Visual C ++ .NET也能產生託管代碼,就是當你創建一個項目,選擇名爲“.Managed”開始的應用程序類型,如“.Managed C++ application”。
What Is Managed Code?
Managed Code is what Visual Basic .NET and C# compilers create. It compiles to Intermediate Language (IL), not to machine code that could run directly on your computer. The IL is kept in a file called an assembly, along with metadata that describes the classes, methods, and attributes (such as security requirements) of the code you've created. This assembly is the one-stop-shopping unit of deployment in the .NET world. You copy it to another server to deploy the assembly there—and often that copying is the only step required in the deployment.
Managed code runs in the Common Language Runtime. The runtime offers a wide variety of services to your running code. In the usual course of events, it first loads and verifies the assembly to make sure the IL is okay. Then, just in time, as methods are called, the runtime arranges for them to be compiled to machine code suitable for the machine the assembly is running on, and caches this machine code to be used the next time the method is called. (This is called Just In Time, or JIT compiling, or often just Jitting.)
As the assembly runs, the runtime continues to provide services such as security, memory management, threading, and the like. The application is managed by the runtime.
Visual Basic .NET and C# can produce only managed code. If you're working with those applications, you are making managed code. Visual C++ .NET can produce managed code if you like: When you create a project, select one of the application types whose name starts with .Managed., such as .Managed C++ application.

什麼是非託管代碼?

非託管代碼是你以前用 Visual Studio .NET 2002創建的代碼。現在你的硬盤驅動器上還有很多Visual Basic 6、Visual C ++ 6,甚至是使用了15年的老C編譯器產生的非託管代碼。非託管代碼直接被編譯成機器碼,跟你具有相同或幾乎相同的芯片的機器上都能運行。但是,它不能從不可見的運行時裏獲得諸如安全或內存管理等服務,而只能從操作系統獲得,通過調用 Windows SDK 提供的 API。最近有越來越多的非託管應用程序通過 COM 調用獲得操作系統的服務。
不同於 Visual Studio 2003 中的其他語言,Visual C ++ 可以創建非託管應用程序。當你創建一個項目,選擇以 MFC、ATL 或 Win32 開頭的應用程序,就創建了一個非託管的應用程序。這導致一些混淆,也就是說,當你創建一個託管的 C++ 應用程序,那麼生成的結果(build product)是一個.exe擴展名的IL裝配文件。當你創建一個 MFC 應用程序,生成的結果(build product)是一個本地代碼的Windows可執行文件,擴展名也是.exe。這兩個文件的內部佈局完全不同。你可以使用中間語言反彙編工具ildasm,查看一下程序集(裝配)的內部,以及元數據文件和IL。如果你用ildasm反彙編一個非託管的.exe文件,那麼你會被告知,沒有有效的CLR頭,不能反彙編——相同的擴展名,但完全不同。
What Is Unmanaged Code?
Unmanaged code is what you use to make before Visual Studio .NET 2002 was released. Visual Basic 6, Visual C++ 6, heck, even that 15-year old C compiler you may still have kicking around on your hard drive all produced unmanaged code. It compiled directly to machine code that ran on the machine where you compiled it—and on other machines as long as they had the same chip, or nearly the same. It didn't get services such as security or memory management from an invisible runtime; it got them from the operating system. And importantly, it got them from the operating system explicitly, by asking for them, usually by calling an API provided in the Windows SDK. More recent unmanaged applications got operating system services through COM calls.
Unlike the other Microsoft languages in Visual Studio, Visual C++ can create unmanaged applications. When you create a project and select an application type whose name starts with MFC, ATL, or Win32, you're creating an unmanaged application.
This can lead to some confusion: When you create a .Managed C++ application., the build product is an assembly of IL with an .exe extension. When you create an MFC application, the build product is a Windows executable file of native code, also with an .exe extension. The internal layout of the two files is utterly different. You can use the Intermediate Language Disassembler, ildasm, to look inside an assembly and see the metadata and IL. Try pointing ildasm at an unmanaged exe and you'll be told it has no valid CLR (Common Language Runtime) header and can't be disassembled—same extension, completely different files.

什麼是本地代碼?

本地代碼在兩種情況下使用。許多人把非託管代碼作爲本地代碼的同義詞:用舊的編譯工具或是 Visual C ++ 生成代碼,不會運行在運行時上,而是在計算機本地。這可能是一個完整的應用,也可能是一個COM組件或DLL,通過COM Interop或PInvoke,由託管代碼調用。這兩個強有力工具可以確保你仍然可以使用你的舊代碼。我更喜歡說非託管代碼。從這個意義上,因爲它強調的是代碼不會得到運行時的服務。例如,託管代碼中代碼的訪問安全性,會阻止代碼從另一個服務裝載代碼,防止破壞性的行爲。如果您的應用程序從另一個服務加載非託管代碼,你就無法得到這種保護。
本地代碼的另一個使用是描述了JIT編譯器的輸出,機器代碼事實上是運行在運行時上。這是託管,但不是IL,而是機器代碼。因此,不能假設本地代碼等於非託管代碼。
What about Native Code?
The phrase native code is used in two contexts. Many people use it as a synonym for unmanaged code: code built with an older tool, or deliberately chosen in Visual C++, that does not run in the runtime, but instead runs natively on the machine. This might be a complete application, or it might be a COM component or DLL that is being called from managed code using COM Interop or PInvoke, two powerful tools that make sure you can use your old code when you move to the new world. I prefer to say .unmanaged code. For this meaning, because it emphasizes that the code does not get the services of the runtime. For example, Code Access Security in managed code prevents code loaded from another server from performing certain destructive actions. If your application calls out to unmanaged code loaded from another server, you won't get that protection.
The other use of the phrase native code is to describe the output of the JIT compiler, the machine code that actually runs in the runtime. It's managed, but it's not IL, it's machine code. As a result, don't just assume that native = unmanaged.

託管代碼意味着託管數據?

對於 Visual Basic 和 C#,生存期問題很簡單,因爲你別無選擇。當你聲明一個類,在託管堆上創建該類的實例,而垃圾回收器關心該實例的生存期問題。但是在 Visual C++,你是有選擇的。即使你創建一個託管應用程序,也可以由你決定類是否是一個託管類型或一個非託管類型。
下面是一個非託管類型:
下面是一個託管類型:
 
唯一的區別是Bar定義前邊的 __gc 關鍵字,但卻有很大不同。關於 __gc 關鍵字參見MSDN:ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_fxintro/html/6a1f9b6c-9983-4722-8b58-13e9af2a1339.htm
託管類型是可以被回收的。它們必須用new來創建,不在堆上。因此,下面是對的:
Foo f;
但下面是不允許的:
Bar b;
如果我必須在堆上創建Foo的一個實例,那一定要記着清除它:
Foo* pf = new Foo(2);
// . . .
delete pf;
在C ++編譯器實際上使用兩個堆,一個是託管的,一個是非託管的,使用重載的new操作符,當創建用一個new創建實例時,來確定分配的內存在哪裏。如果在堆上創建Bar的一個實例,那麼可以忽略它。垃圾回收器將會回收它。在 Visual C++,你是有選擇的。
Does Managed Code Mean Managed Data?
Again with Visual Basic and C#, life is simple because you get no choice. 
When you declare a class in those languages, instances of it are created on the managed heap, and the garbage collector takes care of lifetime issues. 
But in Visual C++, you get a choice. Even when you're creating a managed application, you decide class by class whether it's a managed type or an unmanaged type. 
This is an unmanaged type:
class Foo
{
private:
   int x;
public:
    Foo(): x(0){}
    Foo(int xx): x(xx) {}
};
This is a managed type:
__gc class Bar
{
private:
   int x;
public:
    Bar(): x(0){}
    Bar(int xx): x(xx) {}
};
The only difference is the __gc keyword on the definition of Bar. But it makes a huge difference.
Managed types are garbage collected. They must be created with new, never on the stack. So this line is fine:
Foo f;
But this line is not allowed:
Bar b;
If I do create an instance of Foo on the heap, I must remember to clean it up:
Foo* pf = new Foo(2);
// . . .
delete pf;
The C++ compiler actually uses two heaps, a managed an unmanaged one, and uses operator overloading on new to decide where to allocate memory when you create an instance with new.
If I create an instance of Bar on the heap, I can ignore it. The garbage collector will clean it up some after it becomes clear that no one is using it (no more pointers to it are in scope).
There are restrictions on managed types: They can't use multiple inheritance or inherit from unmanaged types, they can't allow private access with the friend keyword, and they can't implement a copy constructor, to name a few. So, you might not want your classes to be managed classes. But that doesn't mean you don't want your code to be managed code. In Visual C++, you get the choice.
原文地址:http://www.codeguru.com/Csharp/.NET/cpp_managed/article.php/c4871
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章