C # System.NotSupportedException для Marshal.GetFunctionPointerForDelegate - PullRequest
0 голосов
/ 29 ноября 2018

У меня следующая ситуация: у меня 2 DLL-файла c ++, взаимодействующих с приложением C # с помощью событий.Приложение C # передает указатели функций в методе Setup () на оба файла, которые могут позже вызвать событие, используя этот указатель на функцию.Приложение написано для Windows CE 8 и целевого фреймворка Windows Embedded Compact V3.9 (.NET CF 3.9) .

Каждая связь DLL заключена водин класс, содержащий метод Setup () и подкласс NativeMethods, содержащий все методы DLL.Оба DLL-файла имеют событие ItemChanged.

Пример кода:

private delegate void EventDelegate(int item, int value);
private EventDelegate _eventCallback;
private IntPtr _eventCallbackAddress;

private void OnEvent(int item, int value)
{
  Debug.WriteLine("Item: " + item + ", value: " + value);
}

private void Setup()
{
  _eventCallback = new EventDelegate(OnEvent);
  _eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback); // NotSupportedException
  try
  {
    NativeMethods.Configure(_eventCallbackAddress);
  }
  catch (Exception ex)
  {
    Debug.WriteLine(this, ex.Message);
  }
}

private static class NativeMethods
{
  [DllImport("A.dll", EntryPoint = "Configure", CallingConvention = CallingConvention.WinApi)]
  public static extern void Configure(IntPtr eventCallback);
}

Этот фрагмент используется в обоих классах без изменений, кроме ссылки на DllImport.

Моя проблемачто после успешной передачи метода classA.Setup() я получаю исключение System.NotSupportedException при вызове метода Marshal.GetFunctionPointerForDelegate в ClassB.Setup().

Документация MSDN не помогла, и я не нашел никакой дополнительной документации при сканировании через Интернет.Вот почему я пришел сюда.

Я заметил, что исключение не возникает при вызове метода Marshal.GetFunctionPointer для другого «тестового» делегата, но оно все еще выбрасывается на Marshal.GetFunctionPointer(_eventCallback)

private Delegate testDelegate;
private void Foo() { };

private void Setup()
{
  testDelegate = new Action(Foo);
  IntPtr p = Marshal.GetFunctionPointerForDelegate(testDelegate);

  _eventCallback = new EventDelegate(OnEvent);
  _eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback); // NotSupportedException
  try
  {
    NativeMethods.Configure(_eventCallbackAddress);
  }
  catch (Exception ex)
  {
    Debug.WriteLine(this, ex.Message);
  }

У вас есть предложения?Я что-то забыл?

Спасибо.

1 Ответ

0 голосов
/ 30 ноября 2018

Сигнатура ClassB имела параметры общего типа <T, U> для использования общих перечислений на основе int для внешнего интерфейса связи. Допустим, эти перечисления имеют имена RequestItems и ResponseItems.

Во время анализа проблемыкод был закомментирован до тех пор, пока не был получен минимальный рабочий пример.После этого он был пошагово не закомментирован и протестирован - он все еще работал, но после добавления параметров универсального типа <T, U> снова возникло исключение.

Я не ожидал, что сигнатура класса может иметь такиевлияние на системные вызовы методов, такие как Marshal.GetFunctionPointerFromDelegate method.

Рабочий минимальный пример:

public ClassA
{
  private delegate void EventDelegate(int item, int value);
  private EventDelegate _eventCallback;
  private IntPtr _eventCallbackAddress;

  private void OnEvent(int item, int value)
  {
    Debug.WriteLine("Item: " + item + ", value: " + value);
  }

  private void Setup()
  {
    _eventCallback = new EventDelegate(OnEvent);
    _eventCallbackAddress = Marshal.GetFunctionPointerForDelegate(_eventCallback);
    try
    {
      NativeMethods.Configure(_eventCallbackAddress);
    }
    catch (Exception ex)
    {
      Debug.WriteLine(this, ex.Message);
    }
  }

  private static class NativeMethods
  {
    [DllImport("A.dll", EntryPoint = "Configure", CallingConvention = CallingConvention.WinApi)]
    public static extern void Configure(IntPtr eventCallback);
  }
}        

Не рабочий пример - добавьте:

public ClassB<T, U>
{
  //..
}

Спасибо за вашпомощь.

...