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

C#之GCHandle的更多相关文章

  1. 《你不常用的c#之二》:略谈GCHandle

    我们在使用c#托管代码时,内存地址和GC回收那不是我们关心的,CLR已经给我们暗箱操作.但是如果我们在c#中调用了一个非托管代码,比如vc的DLL,而且他有个回调函数,需要引用c#中的某个对象并操作, ...

  2. C# MemoryCache GCHandle

    MemoryCache在项目中用了很久,感觉比较简单,以前也看过里面的源代码,主要借用MemoryCacheStore来完成数据的存储,里面是线程安全的,MemoryCacheStore借用Hasht ...

  3. 【C# .Net GC】手动监视和控制对象的生命周期(GCHandle)

    这个话题还未做详细研究,暂时用不到,只是粗略看了一下. 使用System.Runtime.InteropServices.GCHandle类来手动控制对象的生命周期 (个人感觉这里可能有一些问题... ...

  4. CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总

    CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...

  5. 《你不常用的c#之XX》

    你不常用的c#之一>:略谈unsafe http://blog.csdn.net/robingaoxb/article/details/6199508 <你不常用的c#之二>:略谈G ...

  6. VB6与VB.NET对照表

    VB6与VB.NET对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1.It ...

  7. 简单说说.Net中的弱引用

    弱引用是什么? 要搞清楚什么是弱引用,我们需要先知道强引用是什么.强引用并不是什么深奥的概念,其实我们平时所使用的.Net引用就是强引用.例如: Cat kitty = new Cat(); 变量ki ...

  8. VB6.0 和VB.NET 函数对比

    VB6.0和VB.Net的对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1 ...

  9. cefsharp重写默认js弹窗(alert/confirm/prompt)

    1.设置js弹窗控制器 webView.JsDialogHandler = this;  //js弹窗控制 this表示本类对象,所以本类要实现IJsDialogHandler接口 2.实现IJsDi ...

随机推荐

  1. python进阶__用socket封装TCP

    想要理解socket协议,点击链接,出门左转 一.TCP 通信的服务器端编程的基本步骤: 服务器端先创建一个 socket 对象. 服务器端 socket 将自己绑定到指定 IP 地址和端口. 服务器 ...

  2. 并发编程Bug起源:可见性、有序性和原子性问题

    以前古老的DOS操作系统,是单进行的系统.系统每次只能做一件事情,完成了一个任务才能继续下一个任务.每次只能做一件事情,比如在听歌的时候不能打开网页.所有的任务操作都按照串行的方式依次执行. 这类服务 ...

  3. django_day06

    django_day06 内容回顾 事务 try: with transaction.atomic(): #事务 #一系列的操作 pass except Exception as e: print(e ...

  4. python字典键或值去重

    from fuzzywuzzy import fuzz, process a = {'嫦娥四号探测器是用哪个型号的火箭发射的?': ['长征3B'], '嫦娥四号探测器是在我国[]发射成功的.': [ ...

  5. 不当使用 union all 导致的SQL解析时间过长的问题优化

    在帮助用户优化应用过程中,发现用户大量使用union all 导致SQL解析非常缓慢的问题.考虑到这个问题很有代表意义,我觉得很有必要对于问题进行总结. 一.用户例子 WITH company_use ...

  6. 关于Ubuntu系统无法输入中文的问题,即使做了种种修改

    原网址:https://shurufa.sogou.com/linux/guide 在经历一晚上一及一下午的奋战后,找到了最终解决方案,该解决方案使用的是搜狗输入法 在操作之前有以下注意事项:所有操作 ...

  7. Windows Server体验之SSH远程连接

    经过之前的各种远程管理方法,Windows Server可以被很好的管理,也能符合大多数Windows管理员的使用习惯.不过既然是命令行版本的Windows能不能和Linux一样管理呢?Windows ...

  8. 2021年3月-第02阶段-前端基础-Flex 伸缩布局-移动WEB开发_流式布局

    移动web开发流式布局 1.0 移动端基础 1.1 浏览器现状 PC端常见浏览器:360浏览器.谷歌浏览器.火狐浏览器.QQ浏览器.百度浏览器.搜狗浏览器.IE浏览器. 移动端常见浏览器:UC浏览器, ...

  9. 使用docker-compose.yml安装rabbitmq集群

    1.拉取镜像 集群中每个节点都需要执行 docker pull rabbitmq:3.8.3-management 2.上传docker-compose文件,设置可执行权限 相关文地址:https:/ ...

  10. 支付宝沙箱服务 (结合springboot实现,这里对接的是easy版本,工具用的是IDEA,WebStrom)

    一:打开支付宝开发平台,登录,然后点击控制台 https://open.alipay.com/ 二:滚动到底部,选着沙箱服务 三:获取到对接要用的appId和公钥私钥 四:打开IDEA导入所需的xml ...