2010-05-27 2 views
6

Я действительно смущен множеством дезинформации о родном/управляемом взаимодействии.Вызов собственного обратного вызова из управляемого кода .NET (при загрузке управляемого кода с помощью COM)

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

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

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

Спасибо!

ответ

6

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

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

У Junfeng Zhang есть пример этого here.

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

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

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

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

+0

На шаге 2 указатель функции первоначально поступает в C# -land как IntPtr? – evilfred

+1

Чтобы получить указатель с C/C++ на C#, он будет маршалин. Да, указатели C/C++ представлены как C# 'IntPtr', размер которых зависит от платформы. –

+0

Я, наверное, делаю что-то немое. Компилятор C++ жалуется, что он не может преобразовать мой параметр из voic (__ cdecl *) (UINT) в long (метод принимает IntPtr в C#). Кроме того, пример Чжана включает в себя указатель на функцию C++, полученный на C#, но не один из C++ ... – evilfred

4

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

Смежные вопросы