托管与非托管转换-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);
}
}
}
}