转载 略谈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;
}
}
}

最新文章

  1. 荣品四核4412开发板的USB摄像头问题
  2. 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用
  3. GIT安装完需要做以下配置
  4. 使用jquery修改css中带有!important的样式属性
  5. 为什么会出现ADB rejected shell command
  6. mybatis的简单使用
  7. JavaScript函数学习要点总结(一)
  8. Using Ninject in a Web Application
  9. 点击页面其它地方隐藏该div的方法
  10. 自动化运维工具sshd,expect,pssh,rsync详解
  11. Angularjs中的缓存以及缓存清理
  12. JAVA设计模式——开篇
  13. Linux中如何安装RAR
  14. [Python] 03 - Lists, Dictionaries, Tuples, Set
  15. linux shell实现 URL 编码/解码方法
  16. 微信小程序接入百度统计
  17. OpenCV(2):视频
  18. Beta版本冲刺准备
  19. 第十七篇:IO复用之select实现
  20. 转转转--Java File和byte数据之间的转换

热门文章

  1. Spring的俩大核心概念:IOC、AOP
  2. 说说 JSON 格式的弊端与解决方法
  3. PHP生成唯一不重复的编号
  4. KingbaseES 数据库大小写敏感特性
  5. [开源]React/Vue通用的状态管理框架,不好用你来打我&#128064;
  6. 邮箱的代理发送Send as权限不生效
  7. 图与A*算法
  8. 解决zeal离线文档下载慢问题
  9. Elasticsearch基础但非常有用的功能之二:模板
  10. Prometheus高可用部署