托管与非托管转换-Marshal 类

Marshal是一个方法集合,主要应用在C#和非托管代码交互时,主要有如下方法:

  • 分配非托管内存

  • 复制非托管内存块

  • 将托管类型转换为非托管类型

  • 其他方法(与非托管代码交互时)

  • 常用方法


IntPtr ptr = xxxx;
Data data = new Data();
object obj = data;
ptr ====> data
Marshal.PtrToStructure(ptr, obj);
Marshal.PtrToStructure(ptr, data);
object ret = (Data)Marshal.PtrToStructure(ptr, data.GetType());
Data ret = Marshal.PtrToStructure(ptr);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ConsoleApp2
{
    class Program
    {
       //数组写到非托管内存并读回到托管内存
        static void Main(string[] args)
        {
            //1.创建一个托管内存
            Int64[] managedArray = { 1, 2, 3, 4, };
            int size = Marshal.SizeOf(managedArray[0]) * managedArray.Length;
            //初始化非托管内存以保存数组 pnt 指向非托管内存块的指针
            IntPtr pnt = Marshal.AllocHGlobal(size);
            try
            {
                //把一个数组拷贝到非托管内存中
                Marshal.Copy(managedArray, 0, pnt, managedArray.Length); //重载方法 托管数组拷贝到非拖过数组中
                //拷贝一个非托管数组到另一个托管数组中 
                Int64[] managedArray2 = new Int64[managedArray.Length];
                Marshal.Copy(pnt, managedArray2, 0, managedArray.Length);  //重载方法 非托管数组拷贝到托管数组managedArray2 中
                Console.WriteLine("这个数组被拷贝到一个非托管数组中");
                Console.WriteLine("----");
                Console.WriteLine("The array of unmanaged memory");
                //因为 一个int64 占用8个字节,所以下边的偏移量为 i*8
                for (int i = 0; i < managedArray.Length; i++)
                {
                    Console.Write(Marshal.ReadInt64(pnt, i * 8) + " ");
                }
                Console.Write("\r\n");
                Console.WriteLine("---");
                Console.WriteLine("The back array of unmanaged memory");
                for (int i = 0; i < managedArray.Length; i++)
                {
                    Console.Write(managedArray2[i] + " ");
                }
                Console.Write("\r\n");
                Console.ReadKey();

            }
            finally {
                Marshal.FreeHGlobal(pnt);
            }

        }
    }
}

posted @ 2023-04-12 09:42  丹心石  阅读(166)  评论(0编辑  收藏  举报