C# 托管内存与非托管内存之间的转换
c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存,然而c#毕竟运行在c++之上,有的时候,(比如可能我们需要引入一些第三方的c++或native代码的库,在Unity3d开发中很常见)我们需要直接在c#中操纵非托管的代码,这些non-managed memory我们就需要自己去处理他们的申请和释放了, c# 中提供了一些接口,完成托管和非托管之间的转换,以及对这部分内存的操作。
基本上有以下几种:
1.managed memory-> unmanaged memory
比如在c#中调用第三方的某个c++库,库中有个函数是void func(float * data, int length).我们需要传入给data的就应该是一个非托管的代码(why?首先传入托管的内存,c#层很可能会把它gc掉,而c++还在使用,而且托管的mem它的指针地址可能会发生改变,因此直接传给c++可能拿到的地址是错误的)
代码如下:
using System.Runtime.InteropServices;
float[] _managed_data =... // this is the c# managed data
GCHandle unmanaged_data_handle = GCHandle.Alloc(_managed_data, GCHandleType.Pinned); //这里将标记_managed_data暂时不能被gc回收,并且固定对象的地址
func(unmanaged_data_handle.AddrOfPinnedObject(),_managed_data.Length);//这里将拿到非托管内存的固定地址,传给c++
unmanaged_data_handle.Free();//使用完毕后,将其handle free,这样c#可以正常gc这块内存
2.un-managed memory->managed memory
在c++中返回一个un-managed mem给c#使用。有时需要在c++中分配一块处理好的内存,然后返回给c#来使用,如c++中某个接口 int func(int** data) (注意这里要使用指针的指针,因为data是得到的结果)
IntPtr unmanaged_ptr=IntPtr.Zero; //定义这个c#中用来接收c++返回数据的指针类型
int length = func(out unmanaged_ptr );//调用c++的函数,使unmanaged_ptr指向c++里分配的内存,注意这里用out ,才能与c++里面的**匹配。
byte[] managed_data = new byte[length];
Marshal.Copy(unmanaged_ptr, managed_data, , length);//将非托管内存拷贝成托管内存,才能在c#里面使用
Marshal.FreeHGlobal(unmanaged_ptr);//释放非托管的内存
3.在c#直接申请一个un-managed mem传给c++
有时需要直接在c#开辟一块非托管的内存,传给c++用,这块内存同样可以在c#中用后销毁。代码如下
IntPtr unmanaged_data_prt = Marshal. AllocHGlobal();// 直接分配100 byte的内存
func(unmanaged_data_prt);//传给c++使用
Marshal.FreeHGlobal(unmanaged_data_prt);使用后销毁非托管内存
此外 Marshal类里面还有很多处理非托管内存的方法。
备注
托管内存和非托管内存在c#里面可以互相自由的转化,主要通过Marshal类和GCHandle类,编程时只要注意非托管的内存一定要负责好释放就可以了。
---------------------
C# 托管内存与非托管内存之间的转换的更多相关文章
- C# 中托管内存与非托管内存之间的转换
c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存 ...
- C#内存管理之托管堆与非托管堆( reprint )
在 .NET Framework 中,内存中的资源(即所有二进制信息的集合)分为“托管资源”和“非托管资源”.托管资源必须接受 .NET Framework 的 CLR (通用语言运行时)的管理(诸如 ...
- 如何让IntPtr指向一块内存,以及托管内存与非托管内存的相互转化
IntPtr idp= IntPtr.Zero; StringBuilder idata = new StringBuilder("000000"); string idata = ...
- .net 资源释放(托管资源和非托管资源)
1.托管资源 像int.float.DateTime等都是托管资源:net中80%的资源都是托管资源: 托管资源的回收通过GC(垃圾回收器)自动释放分配给该对象的内存,但无法预测进行垃圾回收的时间,我 ...
- C# 托管资源与非托管资源
在.net 编程环境中,系统的资源分为托管资源和非托管资源. 托管资源: Net平台中,CLR为程序员提供了一种很好的内存管理机制,使得程序员在编写代码时不要显式的去释放自己使用的内存资源(这些在先前 ...
- C# using 三种使用方式 C#中托管与非托管 C#托管资源和非托管资源区别
1.using指令.using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到. ...
- C# 托管资源和非托管资源
托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回 ...
- 托管DLL和非托管DLL的区别
首先解释一下,托管DLL和非托管DLL的区别.狭义解释讲,托管DLL就在Dotnet环境生成的DLL文件.非托管DLL不是在Dotnet环 境生成的DLL文件. 托管DLL文件,可以在Dotnet环境 ...
- C# 托管资源 与 非托管资源
C# 托管资源 与 非托管资源 托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源.例如程序中分配的对象,作用域内的变量 ...
随机推荐
- BZOJ.4820.[SDOI2017]硬币游戏(思路 高斯消元 哈希/AC自动机/KMP)
BZOJ 洛谷 建出AC自动机,每个点向两个儿子连边,可以得到一张有向图.参照 [SDOI2012]走迷宫 可以得到一个\(Tarjan\)+高斯消元的\(O((nm)^3)\)的做法.(理论有\(6 ...
- BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)
BZOJ 洛谷 对树DFS得到括号序列.比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]. 那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[] ...
- BZOJ.2006.[NOI2010]超级钢琴(贪心 堆)
BZOJ 洛谷 思路和BZOJ3784一样,用前缀和+堆维护.做那题吧,不赘述啦. (没错我就是水一个AC) //54620kb 1060ms #include <queue> #incl ...
- Django——ModuleNotFoundError: No module named 'asgiref.sync'
Django+channels运行时报错 Unhandled exception in thread started by <function check_errors.<locals&g ...
- Android:PowerManager类 电源管理
PowerManager类用于对设备电源状态进行管理:PowerManager.WakeLock类用于保持设备常亮:Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现 ...
- 种花 [JZOJ4726] [可撤销贪心]
Description 经过三十多个小时的长途跋涉,小Z和小D终于到了NOI现场——南山南中学.一进校园,小D就被花所吸引了(不要问我为什么),遍和一旁的种花园丁交(J)流(L)了起来. 他发现花的摆 ...
- js 事件冒泡、捕获;call()、apply()
他们是描述事件触发时序问题的术语.事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件.相反的,事件冒泡是自下而上的去触发事件.绑定事件方法的第三个参数,就是控制事件触发顺序是 ...
- sench touch 自定义小图标(转)
自定义图标的方法 Sencha touch自带图标有限,有时需要自己添加图标.下面介绍自定义图标的方法: 首先需要生成图标字体.有许多网站提供在线生成图标字体的功能,比如IcoMoon,通过这个网站, ...
- Spring(2)—IOC
一.Spring IOC是什么 1.简述 Spring是一个开源框架 Spring为简化企业级应用开发而生,使用Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能 Spring是 ...
- 【独家】硅谷创业公司在中国常跌的五个坑|禾赛科技CEO李一帆柏林亚太周主题演讲
[独家]硅谷创业公司在中国常跌的五个坑|禾赛科技CEO李一帆柏林亚太周主题演讲 李一帆 Xtecher特稿作者 关注 Xtecher推荐 演讲者:李一帆 翻译:晓娜 网址:www.xt ...