C#之GCHandle
转载 略谈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的更多相关文章
- 《你不常用的c#之二》:略谈GCHandle
我们在使用c#托管代码时,内存地址和GC回收那不是我们关心的,CLR已经给我们暗箱操作.但是如果我们在c#中调用了一个非托管代码,比如vc的DLL,而且他有个回调函数,需要引用c#中的某个对象并操作, ...
- C# MemoryCache GCHandle
MemoryCache在项目中用了很久,感觉比较简单,以前也看过里面的源代码,主要借用MemoryCacheStore来完成数据的存储,里面是线程安全的,MemoryCacheStore借用Hasht ...
- 【C# .Net GC】手动监视和控制对象的生命周期(GCHandle)
这个话题还未做详细研究,暂时用不到,只是粗略看了一下. 使用System.Runtime.InteropServices.GCHandle类来手动控制对象的生命周期 (个人感觉这里可能有一些问题... ...
- CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总
CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...
- 《你不常用的c#之XX》
你不常用的c#之一>:略谈unsafe http://blog.csdn.net/robingaoxb/article/details/6199508 <你不常用的c#之二>:略谈G ...
- VB6与VB.NET对照表
VB6与VB.NET对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1.It ...
- 简单说说.Net中的弱引用
弱引用是什么? 要搞清楚什么是弱引用,我们需要先知道强引用是什么.强引用并不是什么深奥的概念,其实我们平时所使用的.Net引用就是强引用.例如: Cat kitty = new Cat(); 变量ki ...
- VB6.0 和VB.NET 函数对比
VB6.0和VB.Net的对照表 VB6.0 VB.NET AddItem Object名.AddItem Object名.Items.Add ListBox1.Items.Add ComboBox1 ...
- cefsharp重写默认js弹窗(alert/confirm/prompt)
1.设置js弹窗控制器 webView.JsDialogHandler = this; //js弹窗控制 this表示本类对象,所以本类要实现IJsDialogHandler接口 2.实现IJsDi ...
随机推荐
- qt unknown type name编译报错记录
在classA中include class B,然后定义成员变量的时候,报错unknown type name了. 一共有两种可能造成这种问题: 1.circle include,同时在classA中 ...
- 二极管1N4148和1N4007的区别
二极管1N4148和1N4007的定义 1N4148 是开关二极管,耐压100V,电流150mA,反向恢复速度快,为nS级别. 1N4007 是普通整流二极管,耐压1000V,电流1A ,反向恢复时间 ...
- systemctl_用法总结
查看开机启动项 //查询开机启动项 systemctl list-unit-files // 输出 UNIT FILE 对应服务名:STATE 是状态:enable 是开机启动,disable是开机不 ...
- docker-compose概述--翻译
Overview of Docker Compose 译文 Docker Compose 是一个用来定义和执行多Docker容器程序的工具,如果使用Compose,你将可以使用一个YAML文件来配置你 ...
- Gitea v1.17.0 正式发布 | 集成软件包管理器、容器镜像仓库
我们自豪地宣布 Gitea v1.17.0 发布了.本次发布带来了诸多新特性和累积的更新,我们强烈建议用户在更新到最新版本之前仔细阅读发行注记. 在 1.17.0 版本的开发中我们一共合并了 645 ...
- python 作用域与命名空间
作用域 作用域分为: 全局作用域 局部作用域 在函数内部的作用域叫做局部作用域,局部作用域中的变量叫做局部变量 非函数内部的作用域叫做全局作用域,全局作用域中的变量叫做全局变量 局部作用域可以使用全局 ...
- Bert不完全手册8. 预训练不要停!Continue Pretraining
paper: Don't stop Pretraining: Adapt Language Models to Domains and Tasks GitHub: https://github.com ...
- 升级openssl和openssh脚本
#!/bin/bash # 原先的版本号信息 # openssl version #OpenSSL 1.0.2k-fips 26 Jan 2017 # ssh -V #OpenSSH_7.4p1, O ...
- Elasticsearch:设置Elastic账户安全
- JDK19新特性使用详解
前提 JDK19于2022-09-20发布GA版本,本文将会详细介绍JDK19新特性的使用. 新特性列表 新特性列表如下: JPE-405:Record模式(预览功能) JPE-422:JDK移植到L ...