转载 略谈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. AtCoder Beginner Contest 260 (D-E)

    AtCoder Beginner Contest 260 - AtCoder D - Draw Your Cards 题意:N张卡牌数字 1-n,以某种顺序排放,每次拿一张,如果这一张比前面某一张小( ...

  2. WSUS下载速度和BITS服务

    近日,新装了一台WSUS服务器.选择好需要同步的补丁类型和语言版本后开始等待同步.通过过程异常缓慢,速度一直上不去.同步了一整天才30G,同步3T数据需要100天.这样肯定没办法用,所以要想办法提高下 ...

  3. 【WPF】实现动态切换语言(国际化)以及动态换肤功能

    前言:以下内容,手把手从搭建到最终实现,完成多语言切换以及换装功能. 本地系统环境:win 10 编译器环境:VS2022 社区版 .NET 环境: .NET 6 1.新建一个WPF项目 2.新建完毕 ...

  4. GitHub desktop常见问题及解决办法

    1.There are unresolved conflicts in the working directory. 问题出现:A台电脑push代码后,可能新建了分支,然后B电脑打开GitHub de ...

  5. 使用 EFKLK 搭建 Kubernetes 日志收集工具栈

    转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247491992&idx=1&sn=a770252759 ...

  6. proxysql 开启http监控页面的方法

    update global_variables set variable_value='true' where variable_name='admin-web_enabled'; LOAD ADMI ...

  7. 8.X 的安装配置简化体现

    文章转载自:https://mp.weixin.qq.com/s/CEYYKUub81mk59B3lqAcBA 节点无需任何安全配置,即可实现 TLS 加密通信.Https 加密通信. TLS 应用于 ...

  8. Ceph 存储集群第一部分:配置和部署

    内容来源于官方,经过个人实践操作整理,官方地址:http://docs.ceph.org.cn/rados/ 所有 Ceph 部署都始于 Ceph 存储集群. 基于 RADOS 的 Ceph 对象存储 ...

  9. 使用logstash拉取MySQL数据存储到es中的再次操作

    使用情况说明: 已经使用logstash拉取MySQL数据存储到es中,es中也创建了相应的索引,也存储了数据.假若把这个索引给删除了,再次进行同步操作的话要咋做,从最开始的数据进行同步,而不是新增的 ...

  10. 手把手教你使用LabVIEW OpenCV DNN实现手写数字识别(含源码)

    @ 目录 前言 一.OpenCV DNN模块 1.OpenCV DNN简介 2.LabVIEW中DNN模块函数 二.TensorFlow pb文件的生成和调用 1.TensorFlow2 Keras模 ...