C#之GCHandle
2024-10-20 19:02:24
转载 略谈GCHandle
C# - Marshal.StructureToPtr方法简介
Marshal类 两个方法StructureToPtr和PtrToStructure实现序列化 字节 数组 转换
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks; namespace GCHandleExcerse
{
class Program
{
static void Main(string[] args)
{
People p1 = new People(10,180,"李白");
byte[]buff=Struct2Bytes(p1);
foreach (var i in buff)
{
Console.Write(i+"\t");
}
People p2= ByteToStruct<People>(buff);
Console.WriteLine();
Console.WriteLine(p2.Age+"\t"+p2.Name+"\t"+p2.Height);//输出10 李白 180
Console.ReadKey();
} //结构体转换为byte数组
private static byte[] Struct2Bytes(object o)
{
// create a new byte buffer the size of your struct
byte[] buffer = new byte[Marshal.SizeOf(o)];
// pin the buffer so we can copy data into it w/o GC collecting it
GCHandle bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);//为指定的对象分配句柄,不通过GC回收,而是通过手动释放
// copy the struct data into the buffer
//StructureToPtr参数1:托管对象,包含要封送的数据。该对象必须是格式化类的实例。
//StructureToPtr参数2:指向非托管内存块的指针,必须在调用此方法之前分配该指针。
//StructureToPtr参数3:设置为 true 可在执行Marshal.DestroyStructure方法前对 ptr 参数调用此方法。请注意,传递 false 可导致内存泄漏。
// bufferHandle.AddrOfPinnedObject():检索对象的地址并返回
Marshal.StructureToPtr(o, bufferHandle.AddrOfPinnedObject(), false);//将数据从托管对象封送到非托管内存块。
// free the GC handle
bufferHandle.Free();
return buffer;
} //将byte数组转换为结构体
public static T ByteToStruct<T>(byte[] by) where T : struct
{
int objectSize = Marshal.SizeOf(typeof(T));
if (objectSize > by.Length) return default(T);
// 分配内存
IntPtr buffer = Marshal.AllocHGlobal(objectSize);
// 将数据复制到内存中
Marshal.Copy(by, 0, buffer, objectSize);
// Push the memory into a new struct of type (T).将数据封送到结构体T中
T returnStruct = (T)Marshal.PtrToStructure(buffer, typeof(T));
// Free the unmanaged memory block.释放内存
Marshal.FreeHGlobal(buffer);
return returnStruct;
}
}
struct People
{
public uint Age;
public ushort Height;
public string Name;
public People(uint age, ushort height, string name)
{
this.Age = age;
this.Height = height;
this.Name = name;
}
}
}
最新文章
- 荣品四核4412开发板的USB摄像头问题
- 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用
- GIT安装完需要做以下配置
- 使用jquery修改css中带有!important的样式属性
- 为什么会出现ADB rejected shell command
- mybatis的简单使用
- JavaScript函数学习要点总结(一)
- Using Ninject in a Web Application
- 点击页面其它地方隐藏该div的方法
- 自动化运维工具sshd,expect,pssh,rsync详解
- Angularjs中的缓存以及缓存清理
- JAVA设计模式——开篇
- Linux中如何安装RAR
- [Python] 03 - Lists, Dictionaries, Tuples, Set
- linux shell实现 URL 编码/解码方法
- 微信小程序接入百度统计
- OpenCV(2):视频
- Beta版本冲刺准备
- 第十七篇:IO复用之select实现
- 转转转--Java File和byte数据之间的转换