2014-01-17 3 views
0

GC가/힙에서 물건을 움직일 수 있다는 것을 알고 있습니다. 그러나 메소드에 대한 포인터를 얻는다면, 그 메소드가 이동 될 위험이 있습니까?메소드 주소가 가비지 컬렉터를 통해 이동합니까?

초. 메소드에 대한 포인터가 있다면 안전하지 않거나 빠른 방법으로 호출 할 수 있습니까?

+0

C#에는 포인터가 없습니다. 개체 (또는 대리자)에 대한 참조가 있으므로 이동하는 것에 대해 걱정할 필요가 없습니다. 그들이 그렇게한다면, 당신은 그것을 결코 알 수 없을 것입니다. – Steve

+0

가비지 수집기가 힙을 압축합니다. 그러나 힙을 압축 할 때 메모리 주소 업데이트를 처리합니다. –

+0

@Steve ... C#에는 정확한 포인터 [MSDN] (http://msdn.microsoft.com/en-us/library/t2yzs44b.aspx) – Jim

답변

2

그러나 만약 당신이 방법에 대한 포인터를 얻으면, 그 방법은 움직일 위험이 있습니까?

어떻게 포인터를 메서드에 추가 할 계획입니까? C#에는 이러한 작업이 없습니다!

당신이 한 논쟁을 위해 가정하십시오. 귀하의 질문에 대한 대답은 아니오입니다, 방법은 GC에 의해 이동되지 않습니다. 메서드가 삭제되지 않았습니다.인데, 왜 그들은 으로 이동 했습니까? 삭제로 남겨진 구멍을 압축하기 위해 무언가를 움직입니다.

하지만 C#의 첫 번째 위치에 메서드에 대한 포인터가 없습니다. 당신은 대의원을 얻습니다.

마샬링 코드로 원시 포인터를 얻는 방법은 있지만 그 요점은 무엇입니까? 당신은 그것을 호출 할 수 없습니다.

메소드에 대한 포인터가 있으면 안전하지 않거나 빠른 방법으로 호출 할 수 있습니까?

하지만하지을 그래서 다시, 문제는 무의미하다, C#에서 방법에 대한 포인터를 가지고있다.

위임자를 호출하면 위임자를 호출 할 수 있습니다.

C#에서 메서드에 대한 포인터를 얻는다면 위임자를 만들고 호출하는 것보다 빠르고 가볍게 호출 할 수있는 방법이 있습니까?

C#에서는 컴파일러가 calli 명령어를 생성 할 수있는 방법이 없습니다.

이 기능은 가능합니다.; 한 번 당신이 원하는 기능의 원형으로 놀았습니다. 마지막으로 우선 순위 목록을 보았을 때 그 목록에서 매우 낮았 기 때문에 곧 기대하지는 않았습니다.

+0

내가 관심을 가졌던 정확한 정보. 감사합니다! .추신. F # 또는 Reflection.Emit이 비슷한 작업을 수행 할 수 있습니까? –

+1

@AustinHarris : Calli 명령을 생성하기 위해 Reflection.Emit을 사용하려면 바로 가서 그렇게하십시오.하지만 그렇게하는 것이 대리자를 만드는 것보다 더 많은 작업 일 것이라고 제안합니다. F # 전문가에게 F # 질문을해야합니다. 프로그래밍 전문가로 가득 찬 웹 사이트가있는 경우 ... –

+0

가끔씩 GC로 메소드를 삭제할 수 있습니다. [수집 가능한 어셈블리]가 필요합니다 (http://msdn.microsoft.com/en-us/library/dd554932 (v = .110) .aspx). 일단 더 이상 참조가 없으면 컬렉션이 될 수 있습니다. 여기에는 포함 된 메소드와 JITted 코드 제거가 포함됩니다. 이는 일반 어셈블리에서 정의되지만 수집 가능 어셈블리에서 유형을 사용하는 일반 메소드의 인스턴스화에도 영향을 미칠 수 있습니다. – CodesInChaos

1

이 질문은 관리되지 않는 코드가있는 interop의 컨텍스트에서만 의미가 있다고 생각합니다. CbtHookProc에 대한 썽크 만들고 SetWindowsHookEx에 전달하는 방법을

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); 

[DllImport("user32.dll")] 
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, uint threadId); 

protected int CbtHookProc(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    return Win32.CallNextHookEx(this.cbtHookId, nCode, wParam, lParam); 
} 

// ... 
// keep the delegate reference, avoid "a callback was made on a garbage collected delegate" runtime error 
this.cbtHookProc = new Win32.HookProc(CbtHookProc); 

// install the hook 
this.cbtHookId = Win32.SetWindowsHookEx(Win32.WH_CBT, this.cbtHookProc, 
    IntPtr.Zero, Win32.GetCurrentThreadId()); 

참고 : 예를 들면. think 오브젝트에 할당 된 메모리 조각은 this.cbtHookProc의 수명 시간 동안 고정되어 있으므로 힙 압축 중에 이동하지 않습니다.

1

지금까지 관리되지 않는 함수 포인터를 호출, 당신은 그들을 통해 호출 할 수 있습니다

를 사용하여 하나 또는 모두를, 필요에 따라.

호출 규칙을 올바르게 설정하고 제어 흐름에 필요한 환경 컨텍스트를 함수에 올바르게 설정했는지 확인하십시오 (예 : 일부 기능은 UI 스레드에서 호출 될 것으로 예상됩니다. 당신이 호출하는 함수에)

관련 문제