在VS2005中由DllImport而想到托管和非托管机制

来源:互联网 发布:java框架的书 编辑:程序博客网 时间:2024/06/06 03:47

  今天在使用DllImport导入user32.dll时候,就突发奇想,想自己做个Demo,然后调用,结果发现无法找到入口点。发现了如下就翻译出来。什么是MC,什么UMC,很有帮助。

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..


什么事托管代码?

     托管代码(ManagedCode)是由Visual Basic .NET and C#编译生成德。编译成中间语言Intermediate Language(IL),不是可以直接运行机器码,这个IL是称作一个assembly文件,如:*.DLL等。带有如同classes,methods,attributes等的元数据。

    MC运行在CLR(Common Language Runtime)上,运行机制(runtime)给你的运行code提供了一个很广泛的服务。按照一个流程,首先载入并校验你的IL是OK的。这是才调用(called,invoke)各个方法,运行机制(runtime)把他们便以成适合你机器的机器码,然后这个assembly或者说是中间语言IL就 可以在上运行了。并且运行机制(runtime)还把机器码存储起来用于下次被调用。(原文:and caches this machine code to be used the next time the method is called)。这个称作Just in time 编译(JITTING)。

    当assembly运行时,运行机制(runtime)继续提供各种服务,譬如安全服务,内存管理服务,线程管理等。这些都是由运行机制(runtime)来管理的。

    Visual Basic .NET and C#编译生成MC,如你所愿,你用这个IDE创建工程开发编译时候,生成的是MC。

----------------------------------------------------------
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.

 

什么非托管代码?

    非托管代码(UMC)是你用Visual Studio .NET 2002 发行的编译器:Visual Basic 6, Visual C++ 6, heck,甚至是15年前的C编译器等,编译生成的代码。它直接生成机器码。你在这台机器上编译就生成这台机器的编译码。当然如果另外一台机器如果是一样的芯片等,生成的机器码基本上时一样的。与MC不同了,它不会从隐式的运行机制(Invisible Runtime)获得安全,内存管理.(例如C中声明一个指针,需要自己手动在什么时候释放,而MC则是有一个垃圾回收器会自动做,如同java一个)。而是从操作系统上获取。最重要的是UMC从操作系统里通过询问,调用OS的WIndowSDK的API直接获取。更多的UMC是通过调用COM来获取操作系统服务。
    VC++创建一个UMC应用程序,不像VS中的其他语言。当你创建一个工程,选择MFC,ATL或者Win32等,你创建的就是UM应用。
    这可能有点迷惑:就是说,MC的exe文件是在虚拟器上运行,而UMC是在OS上运行。如:当你创建一个MC的C++应用程序,那么编译生成的是带有.exe的IL的assembly文件。当你创建一个MFC应用,那么编译生成的是带有.exe的windows可执行的本地代码文件。这两个文件内部可以完全不同,你可以使用IL分解器观察一个assembly文件,看看元数据和中间语言IL。如果试着分解一个UMC文件,那么你会被告知这是一个非法CLR文件头,不能被分解(disassembled)。同样的扩展名,完全不同的文件啊。
    实际操作,本人用VS2005载入user32.dll包时候,vs2005会自动关闭。并出现系统出错。

----------------------------------------------------------
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.

什么事本地代码?
    本地代码(NC)有两个意思而存在,许多人把NC与UMC作为同义词使用:
    1.用老的工具编译,或者故意选择不是运行机制(Runtime)如VC++在取代在本地机器上运行,这样可以编译成可以由MC通过COM Interop 或者PInvoke调用的一个app,com或者Dll。COM Interop 和PInvoke是两个重要的工具,当你移植代码到新的环境中,他们可以确保继续使用你的代码,其实这点在VS2005都可以体现了,如VS里转换不同版本等功能。我更喜欢说这层意思是UMC。因为这强调了一个代码没有从运行机制(Invisible Runtime)获取服务。例如,在MC里的代码访问安全机制阻止了从另外带有破坏性的服务载入代码。如果你应用程序从另外服务中载入调用了UMC的话,你应用就得不到保护。
    2.另外意思是:NC是对JIT编译输出的描述,NC实际上时运行在运行机制(Invisible Runtime)上,它被管理,但他不是IL中间语言。是一个机器码。所以不要认为NC等价于UMC。

----------------------------------------------------------
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.

托管代码意味托管数据?

再次提及Visual Basic and C#,生活是很简单因为你没有选择。当你用这些语言声明一个类,他的实例就被创建在托管堆(Mheap)中,并且垃圾回收器会监视他们的生命活动。但是在VC++里,你就可以选择,甚至你要创建一个托管应用,你通过托管类型或非托管类型的class都可以声明一个类。

如下是一个非托管类型的。
class Foo
{
    private:
    int x;
    public:
    Foo(): x(0){}
    Foo(int xx): x(xx) {}
};

下面的是托管类型的。
__gc class Bar
{
    private:
    int x;
    public:
    Bar(): x(0){}
    Bar(int xx): x(xx) {}
};

只是不同的是在Bar前面有“__gc”关键字的定义,但是却有相当不同。
托管类型是由垃圾回收管理的。必须用new来创建对象,从不在栈中,所以可以:Foo f,但是不可以Bar b。
如果你创建一个Foo实例在堆中,你就必须记住要释放他。
Foo *pf = new Foo(2);
//..
delete pf;
C++编译器实际上使用两个堆,一个用于托管,一个用于非托管:并且
当你用new创建实例时就在new上使用操作过载(Operator overloadding)来决定在内存哪里分配空间。
当你在堆中创建Bar实例,我可以或略它,gc可以清除掉不用的对象,(毫无余地地清掉不再使用的对象)
下面是对于托管类型的结束语:他们不能被多重继承,或从一个非托管集成下来,不可以用friend key访问私有的,并且他们不能把一个copy 构造法方法命名其他。所以你也许不想使用托管类了。但是那并不意味你不能要你的代码成为托管代码。在VC++中你还是有选择的。
----------------------------------------------------------