2011-10-27 2 views
0

일부 DLL 파일이 있습니다. 여기에는 이름이 "ABSDefaultCallback"인 몇 가지 메소드가 포함되어 있습니다. 그래서 저는이 방법을 이렇게 할당합니다.Delegete에서 C# 함수의 주소를 얻는 방법은 무엇입니까?

IntPtr hMod = LoadLibrary("bsgui.dll"); 
IntPtr pAddr = GetProcAddress(hMod, "ABSDefaultCallback"); 
op.Callback = pAddr; 

완벽하게 작동합니다. 하지만 "ABSDefaultCallback"을 제외하고 "콜백"이라는 이름의 메서드를 호출하려고합니다. 이런 식으로 해보려고합니다.

DELEGATE_TestFunc fred = new DELEGATE_TestFunc(Callback); 
void* pfred = Marshal.GetFunctionPointerForDelegate(fred).ToPointer(); 
op.Callback = (IntPtr)pfred; 

그러나 이것은 완벽하게 작동하지 않습니다. 내 문제를 해결하는 방법? 고맙습니다.

+0

아마 호출 규칙을. 런타임에 사용자 정의 대리자를 내보내거나 IL에서 작성해야합니다. – leppie

답변

1

p/Invoke를 통해 수행중인 모든 작업에 대해 올바른 서명이 있다고 가정합니다. 그렇지 않으면 먼저 수정해야합니다.

this article에 따르면 대리인이 가비지 수집되는 데 문제가있을 수 있습니다.

대리자에서 GCHandle.Alloc을 사용하여 가비지 수집되지 않는 참조를 만듭니다. 이 당신을 위해 일하게 끝나는 경우

static void DemonstrateCallBack_With_GCHandle() 
{ 
    var callback_delegate = new CallBack(CallBackFunction); 

    GCHandle gch = GCHandle.Alloc(callback_delegate); 
    IntPtr intptr_delegate = 
     Marshal.GetFunctionPointerForDelegate(callback_delegate); 

    PerformActionWithCallBack(intptr_delegate); 

    gch.Free(); 
} 

, 난 당신이 IDisposable를 구현하는 객체의 GCHandle.Allocgch.Free 포장 제안, 그리고 아마도 SafeHandle을 사용으로 보이는 것.

이 문서에서는 관련 세부 사항의 일부를 제공 할 수 있습니다 : http://obiwanjacobi.blogspot.com/2007/05/robust-pinvoke-for-windows-midi-api.html

+0

'PerformActionWithCallBack'에'GCHandle'을 넘기지 않아야합니까? – leppie

+0

@leppie :이 코드는 기사에서 가져온 것입니다. 정보를 전달하는 중입니다. 당신이 말한 것은 제게 완벽하게 이해되는 것처럼 보입니다. 그러나 그것은 그 기사가 한 것이 아닙니다. 나는 실제로 어떻게 작동하는지에 대한 메커니즘을 알지 못한다. 나는 단지 문제를 제출하여 문제를 해결하려고 노력하고있다. :) –

+0

나도 그렇지만 나는해야한다. – leppie

관련 문제