Как получить адрес в функции C # от делегата?

#c# #.net #c #c#-4.0

#c# #.net #c #c #-4.0

Вопрос:

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

 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;
 

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

Комментарии:

1. Вероятно, соглашения о вызовах. Вам нужно будет создать пользовательский делегат во время выполнения или создать в IL.

Ответ №1:

Я предполагаю, что у вас есть правильные подписи для всего, что вы делаете через 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

Комментарии:

1. Вы не должны передавать GCHandle PerformActionWithCallBack кому?

2. @leppie: Этот код взят из статьи, и я просто передаю информацию. То, что вы сказали, кажется, имеет для меня смысл, но это не то, что было в статье. На самом деле я не знаю механику того, как это работает, и я просто пытаюсь представить проблему в Google 🙂

3. Я тоже 🙂 Обычно я не утруждаю себя закреплением указателей, хотя должен.