编程中托管或非托管代码是什么?


150

我在C#代码中使用了特定的命令,效果很好。但是,据说在“非托管”代码中行为不当。

什么是托管或非托管代码?


Answers:


75

这是MSDN上有关非托管代码的一些文字。

一些库代码需要调用非托管代码(例如,本机代码API,例如Win32)。因为这意味着要超出托管代码的安全范围,所以需要格外小心。

这是有关托管代码的其他一些补充说明:

  • 由CLR执行的代码。
  • 面向公共语言运行库的代码(.NET Framework的基础)被称为托管代码。
  • 托管代码提供了CLR提供服务所需的元数据,这些服务包括内存管理,跨语言集成,代码访问安全性以及对象的自动生命周期控制。所有基于IL的代码均作为托管代码执行。
  • 在CLI执行环境下执行的代码。

对于您的问题:

我认为这是因为NUnit为UnitTesting执行您的代码,并且其中的某些部分可能不受管理。但是我不确定,所以不要拿它当黄金。我相信有人可以为您提供更多信息。希望能帮助到你!


12
感谢您为回答做出的努力。但是不知道什么是“托管代码”的人会为您在回答中的意思而苦苦挣扎:他们不会知道:“库代码”,“非托管代码”,“本地代码API”,CLR, .net框架,IL,CLI执行环境等的基础
BKSpurgeon

200

是一篇关于该主题的好文章。

总而言之,

  1. 托管代码不是编译成机器代码,而是编译成一种由机器上的某些服务解释和执行的中间语言,因此可以在(希望!)安全框架中运行,该框架可以为您处理危险的事情,例如内存和线程。在现代用法中,这通常意味着.NET,但不必这样做。

在同一计算机上安装的运行时引擎中执行的应用程序。没有它,该应用程序将无法运行。运行时环境提供了程序使用的软件例程的常规库,并且通常执行内存管理。它还可以提供从源代码到可执行代码或从中间语言到可执行代码的即时(JIT)转换。Java,Visual Basic和.NET的公共语言运行时(CLR)是运行时引擎的示例。(阅读更多

  1. 非托管代码被编译为机器代码,因此直接由OS执行。因此,它具有执行破坏性/强大功能的能力,而托管代码则没有。这就是过去所有事物的工作方式,因此通常将其与.dll等旧内容相关联。

自行运行的可执行程序。从操作系统启动,该程序将调用并使用操作系统中的软件例程,但是不需要使用其他软件系统。对于特定平台,已经被汇编为机器语言的汇编语言程序和被汇编为机器语言的C / C ++程序就是非托管代码的示例。(阅读更多

  1. 本机代码通常是Unmanaged的同义词,但并不完全相同。

你的意思是在黑客攻击中我们不能使用.net langauge(C#,C ++),对吗?
Haroon A. 2012年

7
@H_wardak您如何定义“黑客”?这是一个非常笼统的术语,就像说入侵NORAD和入侵某些寄存器一样。
亚历克斯

7
面试官曾经问过我,我们可以在C#中运行/编写非托管代码吗?有人可以帮忙吗?
RSB

8
@RSB:您不能用C#编写非托管代码(尽管您可以直接从C#调用非托管代码)。从理论上讲,如果使用正确的编译器和框架,您可以做到。实际上,这意味着您需要一个可以将C#直接编译为机器代码的编译器。不确定如何运作。
詹姆斯·豪格

67

当您想到非托管时,请考虑机器特定的机器级代码。类似于x86汇编语言。非托管(本机)代码经过编译和链接,可直接在其设计的处理器上运行,此刻不包括所有操作系统内容。它不是便携式的,但速度很快。非常简单,精简的代码。

托管代码包括从Java到旧的Interpretive BASIC的所有内容,或在.NET下运行的所有内容。通常将托管代码编译为中间级别的P代码或字节代码指令集。尽管它们看起来类似于汇编语言,但它们不是特定于机器的指令。托管代码将程序与运行它的计算机隔离开来,并创建一个安全边界,在该边界中间接分配所有内存,通常来说,您无法直接访问机器资源,例如端口,内存地址空间,堆栈等。这个想法是在更安全的环境中运行。

要从托管变量转换为非托管变量,您必须先到达实际对象本身。它可能被包裹或装在其他包装中。在32位计算机上,非托管变量(例如“ int”之类的变量)恰好占用4个字节。没有开销或其他包装。从托管代码变为非托管代码,然后再返回的过程称为“ 封送处理 ”。它允许您的程序越过边界。


1
混搭处理如何与值和引用类型交互?我记得例如看到过有关MarshalByRefObject的内容。
凯尔·巴兰

24

用尽可能少的词:

  • 托管代码= .NET程序
  • 非托管代码=“常规”程序

16
.NET程序不是“正常”的吗?
jtate

1
@jtate-有点傻了,是的。:)我试图使其更加直观。无论如何,那是8年前了。如今,在日常使用中的编程语言种类繁多,这种区分的确更加不精确,是的。
Vilx-

5

托管代码是C#.Net,VB.Net,F#.Net等编译器创建的。它运行在CLR上,除其他功能外,CLR还提供垃圾收集,引用检查等服务。因此,我的代码由CLR管理。

另一方面,非托管代码直接编译为机器代码。它不是由CLR管理的。


4

基本上,非托管代码是指不能在.NET CLR下运行的代码(又名不是VB.NET,C#等)。我的猜测是NUnit具有不是.NET代码(也称为C ++)的运行程序/包装程序。


4

托管代码:
与公共语言运行库在“合作合同”下运行的代码。托管代码必须提供运行时所需的元数据,以提供服务,例如内存管理,跨语言集成,代码访问安全性以及对象的自动生命周期控制。所有基于Microsoft中间语言(MSIL)的代码均作为托管代码执行。

非托管代码:
创建的代码不考虑公共语言运行时的约定和要求。非托管代码在公共语言运行时环境中以最少的服务(例如,无垃圾收集,有限的调试等)执行。

参考:http : //www.dotnetspider.com/forum/11612-difference-between-managed-and-unmanaged-code.aspx


3

NUnit将单元测试加载到单独的AppDomain中,并且我假设未调用入口点(可能不需要),因此入口程序集为null。


2

托管代码在CLR(即.NET运行时)环境中运行。简而言之,所有IL都是托管代码。但是,如果您使用的是第三方软件示例VB6或VC ++组件,则它们是非托管代码,因为.NET运行时(CLR)无法控制语言的源代码执行。


1

托管代码:-MSIL(中间语言)形式的代码是在语言编译器编译后开发的,并由被CLR调用的托管代码直接执行。例如:-.net框架支持所有61种语言代码

非托管代码:-之前开发的代码,.net其MSIL形式不可用,而是CLR直接由其执行CLR将其重定向到操作系统,这称为非托管代码。

例如:-COM,Win32 API


这篇文章有很多错误。最明显的是MISL(您的意思是MSIL)。
马特·西摩

1
  • 托管代码:用.NET语言编写的代码,例如C#,VB.NET。
  • 非托管代码:不是用.NET语言编写的代码,MSIL无法理解它的含义,并且不能在CLR下运行;就像我们在.NET应用程序中使用的不是以.NET语言创建的第三方控件一样。

0

首先前理解这一点,.NET frameworkMicrosoft分别提供了独立的产品,如MFC (Visual C++), VB, FoxPro等。

2002年,Microsoft组合了其产品并制作了.NET框架。现在,之前的代码执行方式与.NET框架中的代码管理和执行方式之间存在差异。微软引入CLR了.NET框架的概念,该概念可编译来自.NET框架的任何受支持的语言的代码,并提供诸如memory mangement, garbage collection等的其他功能。但是,此类CLR功能以前无法直接使用。

因此,如果要在.NET框架(使用CLR编译)中创建库/代码,则称为Managed code。您可以在其他.NET应用程序/项目中进一步使用此库,CLR也会在那里了解其以前的编译方式,因此它仍然是您的管理代码。

OTOH如果您想使用在.NET Framework之前编写的库,则可以做一些限制,但是请记住,由于当时还没有CLR,所以现在,CLR将不再理解并重新编译此代码。 。这将被称为unmanaged code。请注意,由第三方创建以提供某些功能/工具的库/组件也可能被视为非管理代码,如果它们不兼容CLR。

用外行术语来说,“ 管理代码”是您的CLR理解的,可以自行编译以进一步执行。在.NET Framework中,(使用.NET Framework上的任何语言)当代码进入CLR时,代码将提供一些元数据信息,以便CLR可以为您提供此处指定的功能。他们很少是Garbage collection, Performance improvements, cross-language integration, memory management等等。

OTOH,未经处理的代码是计算机专用的,可以立即使用,无需进一步处理。


恐怕很多很多不知情的意见。这可能令人惊讶,但是CLR也可以执行非托管代码(通常以C ++ / CLI编写)。也不需要托管代码作为IL提供。.NET Native已经存在了一段时间,它带有预编译的程序集。您所谓的“ CLR兼容”可能意味着“ CLS兼容”。突然无法满足CLS规范并不能使托管代码不受管理。使用非托管代码-尽管有您的描述-也很容易(通过COM进行RW,P / Invoke,C ++ / CLI等)。
IInspectable

0

从Pro C#5和.NET 4.5框架中:

托管代码与非托管代码: 了解C#语言最重要的一点是,它可以生成只能在.NET运行时内执行的代码(您永远无法使用C#来构建本机COM服务器或非托管C / C ++应用)。正式来说,用于描述针对.NET运行时的代码的术语是托管代码。包含托管代码的二进制单元称为程序集(稍后将详细介绍程序集)。相反,不能由.NET运行时直接托管的代码称为非托管代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.