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, 0, length);//将非托管内存拷贝成托管内存,才华在c#里面使用 Marshal.FreeHGlobal(unmanaged_ptr);//释放非托管的内存
3.在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类里面还有很多措置惩罚惩罚非托管内存的要领
标签:
原文地点:https://www.cnblogs.com/jshchg/p/12785807.html