在C#中,System.Runtime.InteropServices.Marshal类是一个非常重要的类,它提供了一组方法和属性,用于在托管代码与非托管代码之间进行数据的互操作(Interop)。这包括分配和释放非托管内存、复制数据、以及处理非托管函数指针等功能。简而言之,Marshal类是托管代码(.NET 应用程序)和非托管代码(如C++编写的动态链接库DLL)之间的桥梁。

Marshal类的一些主要用途包括:

  1. 内存分配和释放

    • AllocHGlobalAllocCoTaskMem方法用于在非托管内存中分配内存。
    • FreeHGlobalFreeCoTaskMem方法用于释放那些通过AllocHGlobalAllocCoTaskMem分配的内存块。
  2. 数据复制

    • Copy系列方法允许将数据从托管数组复制到非托管内存,或者从非托管内存复制到托管数组中。
    • PtrToStructureStructureToPtr方法用于将数据从非托管内存块复制到托管结构体,或将托管结构体的数据复制到非托管内存。
  3. 处理非托管函数指针

    • GetDelegateForFunctionPointer方法可以将非托管函数指针转换为相应的托管委托。
    • GetFunctionPointerForDelegate方法可以获得与托管委托相对应的非托管函数指针。
  4. 字符串处理

    • StringToHGlobalAnsiStringToHGlobalUni等方法用于将托管字符串转换为非托管内存中的字符串。
    • PtrToStringAnsiPtrToStringUni等方法用于将非托管内存中的字符串转换为托管字符串。
  5. 获取非托管类型的大小

    • 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来处理非托管资源,是处理非托管代码的强大工具。

最后修改:2024 年 06 月 20 日
如果觉得我的文章对你有用,请随意赞赏