在C#中,System.Runtime.InteropServices.Marshal
类是一个非常重要的类,它提供了一组方法和属性,用于在托管代码与非托管代码之间进行数据的互操作(Interop)。这包括分配和释放非托管内存、复制数据、以及处理非托管函数指针等功能。简而言之,Marshal
类是托管代码(.NET 应用程序)和非托管代码(如C++编写的动态链接库DLL)之间的桥梁。
Marshal
类的一些主要用途包括:
内存分配和释放:
AllocHGlobal
和AllocCoTaskMem
方法用于在非托管内存中分配内存。FreeHGlobal
和FreeCoTaskMem
方法用于释放那些通过AllocHGlobal
或AllocCoTaskMem
分配的内存块。
数据复制:
Copy
系列方法允许将数据从托管数组复制到非托管内存,或者从非托管内存复制到托管数组中。PtrToStructure
和StructureToPtr
方法用于将数据从非托管内存块复制到托管结构体,或将托管结构体的数据复制到非托管内存。
处理非托管函数指针:
GetDelegateForFunctionPointer
方法可以将非托管函数指针转换为相应的托管委托。GetFunctionPointerForDelegate
方法可以获得与托管委托相对应的非托管函数指针。
字符串处理:
StringToHGlobalAnsi
、StringToHGlobalUni
等方法用于将托管字符串转换为非托管内存中的字符串。PtrToStringAnsi
、PtrToStringUni
等方法用于将非托管内存中的字符串转换为托管字符串。
获取非托管类型的大小:
SizeOf
方法用于获取非托管类型或托管结构体的大小,这在分配非托管内存时非常有用。
示例:复制数据到非托管内存
以下示例演示了如何使用Marshal
类将一个整数数组复制到非托管内存,并最终释放该内存:
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
int size = Marshal.SizeOf(typeof(int)) * numbers.Length;
// 在非托管内存中分配空间
IntPtr ptr = Marshal.AllocHGlobal(size);
try
{
// 将托管数组复制到非托管内存
Marshal.Copy(numbers, 0, ptr, numbers.Length);
// 从非托管内存读取数据...
}
finally
{
// 释放非托管内存
Marshal.FreeHGlobal(ptr);
}
}
}
Marshal
类是.NET应用程序中实现托管与非托管代码互操作的关键类,它提供了丰富的API来处理非托管资源,是处理非托管代码的强大工具。