非托管代码库指的是不由 .NET 运行时(也称为 CLR,公共语言运行时)进行管理的代码。非托管代码通常是指用诸如 C、C++ 或者 Delphi 等编程语言编写的代码,这些代码直接编译成机器码,并且在运行时不依赖于 .NET 框架的托管环境。非托管代码主要依赖操作系统提供的服务进行内存管理、类型安全和异常处理。
与之相对,托管代码是指运行在 .NET 运行时之上的代码,这些代码由 CLR 提供的服务进行管理,包括内存管理(垃圾回收)、安全性检查、异常处理和类型安全等。C#、VB.NET 和 F# 编写的代码通常都是托管代码。
非托管代码库的特点
-
内存管理:
- 非托管代码需要显式地进行内存管理,程序员负责分配和释放内存(例如,使用
malloc
和free
在 C 语言中)。 - 托管代码的内存管理由 CLR 进行,自动进行垃圾回收。
- 非托管代码需要显式地进行内存管理,程序员负责分配和释放内存(例如,使用
-
类型安全:
- 非托管代码通常缺乏严格的类型安全检查,容易引发类型错误或内存损坏。
- 托管代码在编译时和运行时都有严格的类型安全检查。
-
异常处理:
- 非托管代码使用操作系统提供的异常处理机制(如 Windows 的 SEH)。
- 托管代码使用 .NET 的异常处理机制,提供统一的异常处理模型。
-
平台依赖性:
- 非托管代码通常是平台依赖的,因为它直接编译成特定操作系统的机器码。
- 托管代码通过 CLR 提供的平台无关性,可以在支持 .NET 的不同平台上运行。
例子
非托管代码库示例 ©:
// example.c
#include <stdio.h>
void HelloWorld()
{
printf("Hello, World!\n");
}
托管代码调用非托管理代码库示例 (C#):
using System;
using System.Runtime.InteropServices;
class Program
{
// 导入非托管函数
[DllImport("example.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void HelloWorld();
static void Main()
{
// 调用非托管函数
HelloWorld();
}
}
在这个例子中,example.dll
是一个非托管代码库,包含一个用 C 编写的简单函数 HelloWorld
。在 C# 程序中,通过使用 DllImport
特性导入这个非托管函数,并在托管代码中调用它。这样就实现了托管代码与非托管代码之间的互操作。