Unity 托管代码与非托管代码
你提到的“托管代码”与“与托管代码”似乎是对术语的重复或笔误。这里我会解释 托管代码 和 非托管代码(通常是与托管代码相对的概念),以及它们的区别。
1. 托管代码(Managed Code)
托管代码 是由 .NET 运行时(如 CLR,即公共语言运行时)托管和管理的代码。也就是说,托管代码的执行是在 CLR 环境中进行的,CLR 提供了内存管理、异常处理、垃圾回收、安全性等功能。这意味着开发者无需自己管理内存分配和释放,CLR 会负责这些操作。
特点:
- 内存管理:托管代码的内存管理是由垃圾回收器(GC,Garbage Collector)自动处理的。
- 类型安全:CLR 会确保类型的安全性,例如防止类型转换错误、非法内存访问等。
- 自动垃圾回收:CLR 会定期回收不再使用的内存空间,避免内存泄漏。
- 安全性:CLR 会进行代码的安全检查,确保代码不会执行恶意操作。
- 平台独立性:托管代码一般是通过 中间语言(IL,Intermediate Language) 编译的,这样可以通过不同平台上的 CLR 实现执行。
托管代码的一个例子就是 C# 中编写的代码,它会被编译成 中间语言(IL),然后在 .NET 环境中运行。
例如:
1 | using System; |
上面的代码就是托管代码,它会被 C# 编译器编译为中间语言(IL),然后通过 CLR 执行。
2. 非托管代码(Unmanaged Code)
非托管代码 是指不由 CLR 或类似的运行时环境管理的代码。这类代码直接与操作系统交互,开发者必须手动管理内存、资源和安全性等问题。非托管代码通常是用 C++、C 或其他低级语言编写的。
特点:
- 手动内存管理:开发者需要自己负责分配和释放内存,容易出现内存泄漏问题。
- 直接访问硬件:非托管代码能够直接操作硬件,进行系统级别的操作。
- 无垃圾回收:没有像 CLR 那样的垃圾回收机制,必须手动释放资源。
- 性能优势:由于没有运行时环境的管理,非托管代码通常比托管代码更加高效,尤其是在对性能要求极高的场景下。
非托管代码通常被编译为机器码并直接运行在操作系统上。
例如:
1 |
|
上面的 C++ 代码是非托管代码,它被编译为机器代码,直接在操作系统中执行。
3. 托管代码与非托管代码的区别
特性 | 托管代码 | 非托管代码 |
---|---|---|
执行环境 | 运行在 CLR(公共语言运行时)中 | 直接运行在操作系统上 |
内存管理 | 自动由 垃圾回收器(GC) 管理 | 需要开发者手动管理内存 |
类型安全 | 自动进行类型检查,防止类型错误 | 可能会发生类型错误,必须手动管理 |
安全性 | CLR 进行安全检查,防止恶意代码执行 | 代码可能没有安全性保障,易受攻击 |
性能 | 性能较低,因为有垃圾回收等运行时开销 | 性能较高,因为没有运行时环境的开销 |
示例语言 | C#、VB.NET、F# 等 | C、C++ 等 |
可移植性 | 通过中间语言(IL)可以跨平台运行 | 必须针对每个平台进行编译 |
4. 托管代码与非托管代码的交互
虽然托管代码和非托管代码有很多差异,但在实际应用中,它们经常需要互相交互,特别是在需要访问系统底层或与已有的非托管代码库集成时。通常有几种方式来实现托管代码与非托管代码的交互:
P/Invoke(平台调用):托管代码可以通过 P/Invoke 调用非托管的 API(例如 Windows API)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14using System;
using System.Runtime.InteropServices;
class Program
{
[ ]
public static extern IntPtr GetConsoleWindow();
static void Main()
{
IntPtr hwnd = GetConsoleWindow();
Console.WriteLine(hwnd);
}
}以上是通过 P/Invoke 调用 Windows 的非托管函数
GetConsoleWindow
。C++/CLI(C++ 和托管代码混合):C++/CLI 是一种可以同时操作托管代码和非托管代码的语言,可以方便地在同一项目中混合使用 C++(非托管代码)和 C#(托管代码)。
1
2
3
4
5
6
7
8
9
using namespace System;
public ref class ManagedClass {
public:
void PrintMessage() {
Console::WriteLine("Hello from C++/CLI!");
}
};COM(组件对象模型):通过 COM 机制,非托管代码可以通过 COM 接口与托管代码进行交互。
5. 总结
- 托管代码 是由 .NET 运行时管理的代码,它具有内存管理、安全性和平台独立性的优势。常见的托管语言包括 C# 和 VB.NET。
- 非托管代码 是直接运行在操作系统上的代码,需要开发者手动管理内存和资源,常见的非托管语言包括 C 和 C++。
- 在很多情况下,托管代码和非托管代码是需要协同工作的,Unity 中通常使用托管代码(如 C#),但在需要性能或底层系统调用时,也可以使用非托管代码(如 C++)。