托管、非托管、本地:这些代码有什么区别?

托管、非托管、本地:这些代码有什么区别?
随着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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值