C# 托管内存与非托管内存之间的转换(结合Unity3d的实际开发)
来源:互联网 发布:阿里云备案拍照 编辑:程序博客网 时间:2024/06/05 11:25
1.c#的托管代码和非托管代码
c#有自己的内存回收机制,所以在c#中我们可以只new,不用关心怎样delete,c#使用gc来清理内存,这部分内存就是managed memory,大部分时候我们工作于c#环境中,都是在使用托管内存,然而c#毕竟运行在c++之上,有的时候,(比如可能我们需要引入一些第三方的c++或native代码的库,在Unity3d开发中很常见)我们需要直接在c#中操纵非托管的代码,这些non-managed memory我们就需要自己去处理他们的申请和释放了, c# 中提供了一些接口,完成托管和非托管之间的转换,以及对这部分内存的操作。基本上有以下几种:
2.managed mem-> un-managed mem
比如在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这块内存
3.un-managed mem->managed mem, 在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, 0, length);//将非托管内存拷贝成托管内存,才能在c#里面使用
Marshal.FreeHGlobal(unmanaged_ptr);//释放非托管的内存
4.在c#直接申请一个un-managed mem传给c++
有时需要直接在c#开辟一块非托管的内存,传给c++用,这块内存同样可以在c#中用后销毁。代码如下
IntPtr unmanaged_data_prt = Marshal. AllocHGlobal(100);// 直接分配100 byte的内存
func(unmanaged_data_prt);//传给c++使用
Marshal.FreeHGlobal(unmanaged_data_prt);使用后销毁非托管内存
此外 Marshal类里面还有很多处理非托管内存的方法。
托管内存和非托管内存在c#里面可以互相自由的转化,主要通过Marshal类和GCHandle类,编程时只要注意非托管的内存一定要负责好释放就可以了。
- C# 托管内存与非托管内存之间的转换(结合Unity3d的实际开发)
- C# 托管内存与非托管内存之间的转换(结合Unity3d的实际开发)
- C# 托管内存与非托管内存之间的转换
- 内存的释放--托管与非托管
- 需要这样一个记录本-1 C#托管内存与非托管内存相互转换
- .net内存释放(托管堆与非托管堆的释放)
- 托管C++的String^类型与非托管C++的char*类型之间的转换
- C#内存管理-栈堆/回收器托管/非托管资源释放/指针的应用
- C#托管和非托管的资源(二)——后台内存管理
- c#的内存管理(托管及未托管对象管理)
- 【笔试&面试】C#的托管代码与非托管代码
- 关于C#托管代码与非托管代码的理解
- 关于C#托管代码与非托管代码的简述
- C#的内存管理:堆栈、托管堆与指针
- C#的内存管理:堆栈、托管堆与指针
- 【转】C#的内存管理:堆栈、托管堆与指针
- C#的内存管理:堆、栈、托管堆与指针
- C#的内存管理:堆栈、托管堆与指针
- 第十六周项目四 为动态数组扩容
- 用Java实现断点续传(HTTP)
- 第十六周项目4为动态数组扩容
- hdu 4888 Redraw Beautiful Drawings
- Bonjour/Zeroconf with Arduino
- C# 托管内存与非托管内存之间的转换(结合Unity3d的实际开发)
- C++中的时间函数
- the file “XXX” could not be opened because you don't have permission to view it
- JS 原型(prototype)详解
- 大数据时代的4个V
- Processing学习笔记---基本结构
- 第十六周项目一 数组的排序
- 第十六周OJ(3)
- 第16周项目--OJ平台是否有相同的数字