Как получить адрес в функции C # от делегата? - PullRequest
0 голосов
/ 27 октября 2011

У меня есть файл DLL. Он содержит какой-то метод с именем «ABSDefaultCallback». Поэтому я назначаю этот метод следующим образом.

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

это работа на отлично. Но я хочу вызвать свой собственный метод с именем «Callback», кроме «ABSDefaultCallback». Я пытаюсь сделать это так.

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

Но этот не работает идеально. Как исправить мою проблему?

1 Ответ

1 голос
/ 27 октября 2011

Я предполагаю, что у вас есть правильные подписи для всего, что вы делаете через p / Invoke.Если вы этого не сделаете, то вам нужно сначала исправить это.

Согласно этой статье , возможно, у вас возникла проблема с сборкой мусора вашего делегата.

Они используют 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();
}

Если это сработает для вас, я бы посоветовал вам обернуть GCHandle.Alloc и gch.Free в объекте, который реализует IDisposable и, возможно, рассмотрит использование SafeHandle.

В этой статье могут быть приведены некоторые соответствующие подробности: http://obiwanjacobi.blogspot.com/2007/05/robust-pinvoke-for-windows-midi-api.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...