Вызов собственного обратного вызова из управляемого кода .NET (при загрузке управляемого кода с помощью COM) - PullRequest
6 голосов
/ 28 мая 2010

Я действительно смущен множеством дезинформации о нативном / управляемом взаимодействии.

У меня есть обычный C ++ exe, который НЕ построен с использованием CLR (это не Managed C ++ или C ++ / CLI и никогда не будет). Этот C ++ exe "отвечает", для него нет управляемой оболочки.

Я хотел бы получить доступ к некоторому коду в сборке C # из моего C ++ exe. Я могу получить доступ к сборке C # из моего кода C ++, используя COM. Однако, когда мой код C # обнаруживает событие, я бы хотел, чтобы он вызывал мой код C ++. Указатель на функцию C ++ для обратного вызова будет предоставлен во время выполнения. Обратите внимание, что указатель на функцию C ++ относится к функции, найденной в среде выполнения exe. Он может использовать статические члены оттуда. Я не хочу, чтобы управляемый код пытался загрузить некоторую DLL-библиотеку для вызова функции (нет DLL).

Как передать этот указатель функции C ++ на мой код C # через COM / .NET, и чтобы мой код C # успешно вызывал его?

Спасибо!

Ответы [ 2 ]

7 голосов
/ 28 мая 2010

Возможно, вы захотите использовать Marshal.GetDelegateForFunctionPointer:

  1. Создайте тип делегата, который соответствует сигнатуре нативной функции, помня о правильном способе маршалинга типов и используя MarshalAs при необходимости
  2. Сообщите указатель встроенной функции из собственного кода в код C #, насколько это возможно (в вашем случае, похоже, вы можете использовать ваше соединение COM -> C #)
  3. Используйте Marshal.GetDelegateForFunctionPointer, чтобы превратить указатель в C # -калибируемый делегат
  4. Вызовите делегата с вашими параметрами

У Джунфэна Чжана есть пример сделать это здесь .

Обратите внимание на ограничения, указанные в MSDN:

GetDelegateForFunctionPointer Метод имеет следующие ограничения:

  • Общие не поддерживаются во взаимодействии сценарии.
  • Вы не можете передать недопустимую функцию указатель на этот метод.
  • Вы можете использовать этот метод только для чистого указатели неуправляемых функций.
  • Вы не можете использовать этот метод с указатели на функции, полученные через C ++ или из метода GetFunctionPointer.
  • Вы не можете использовать этот метод для создания делегировать от указателя на функцию другой управляемый делегат.

Часть о C ++, вероятно, относится к указателям на функции для методов класса. Это все еще должно работать для глобальных функций.

4 голосов
/ 28 мая 2010

Стандартный подход COM состоит в том, чтобы подписаться на событие, которое вызывается сервером COM. Use может использовать ключевое слово event в C #, CLR interop автоматически реализует необходимый COM-клей. Используйте интерфейс IConnectionPoint в своем коде C ++. Backgrounder здесь .

...