略談GCHandle【轉】
略談GCHandle【轉】
http://blog.163.com/vk_01313/blog/static/17219228200912491729457/
我們在使用c#托管代碼時,內存地址和GC回收那不是我們關心的,CLR已經給我們暗箱操作。
但是如果我們在c#中調用了一個非托管代碼,比如vc的DLL,而且他有個回調函數,需要引用c#中的某個對象并操作,
這時候你就得要小心了。
要是非托管代碼中用到得托管代碼那個對象被GC給回收了,這時候就會報內存錯誤。
所以我們就要把那個對象“釘”住(pin),讓它的內存地址固定,而不被垃圾回收掉,然后最后我們自己管理,自己釋放內存,這時候就需要GCHandle,來看個msdn上的例子:
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
//C#
public delegate bool CallBack(int handle, IntPtr param);
public class LibWrap
{
[DllImport("user32.dll")]
public static extern bool EnumWindows(CallBack cb, IntPtr param);
}
class Program
{
static void Main(string[] args)
{
TextWriter tw = System.Console.Out;
GCHandle gch = GCHandle.Alloc(tw);
CallBack cewp = new CallBack(CaptureEnumWindowsProc);
LibWrap.EnumWindows(cewp, (IntPtr)gch);
gch.Free();
Console.Read();
}
private static bool CaptureEnumWindowsProc(int handle, IntPtr param)
{
GCHandle gch = (GCHandle)param;
TextWriter tw = (TextWriter)gch.Target;
tw.WriteLine(handle);
return true;
}
}
}
對上面的代碼,略加解釋:gch 會釘住(pin)tw這個對象,使其不受GC管理,告訴它,以后你崩管我,我也不用給你上稅,其實管理權已經給gch,通過free來釋放內存。
這種情況主要用在托管和非托管代碼交互的時候,防止內存泄露來使用GCHandle。
http://blog.163.com/vk_01313/blog/static/17219228200912491729457/
我們在使用c#托管代碼時,內存地址和GC回收那不是我們關心的,CLR已經給我們暗箱操作。
但是如果我們在c#中調用了一個非托管代碼,比如vc的DLL,而且他有個回調函數,需要引用c#中的某個對象并操作,
這時候你就得要小心了。
要是非托管代碼中用到得托管代碼那個對象被GC給回收了,這時候就會報內存錯誤。
所以我們就要把那個對象“釘”住(pin),讓它的內存地址固定,而不被垃圾回收掉,然后最后我們自己管理,自己釋放內存,這時候就需要GCHandle,來看個msdn上的例子:
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
//C#
public delegate bool CallBack(int handle, IntPtr param);
public class LibWrap
{
[DllImport("user32.dll")]
public static extern bool EnumWindows(CallBack cb, IntPtr param);
}
class Program
{
static void Main(string[] args)
{
TextWriter tw = System.Console.Out;
GCHandle gch = GCHandle.Alloc(tw);
CallBack cewp = new CallBack(CaptureEnumWindowsProc);
LibWrap.EnumWindows(cewp, (IntPtr)gch);
gch.Free();
Console.Read();
}
private static bool CaptureEnumWindowsProc(int handle, IntPtr param)
{
GCHandle gch = (GCHandle)param;
TextWriter tw = (TextWriter)gch.Target;
tw.WriteLine(handle);
return true;
}
}
}
對上面的代碼,略加解釋:gch 會釘住(pin)tw這個對象,使其不受GC管理,告訴它,以后你崩管我,我也不用給你上稅,其實管理權已經給gch,通過free來釋放內存。
這種情況主要用在托管和非托管代碼交互的時候,防止內存泄露來使用GCHandle。
posted on 2015-12-21 18:36 天下 閱讀(945) 評論(0) 編輯 收藏 引用 所屬分類: C#