У меня есть следующие настройки:
Родной проект объявляет
class Native
{
public:
virtual void Add(int a);
};
который реализован в смешанном режиме проекта:
class Mixed : public Native
{
public:
virtual void Add(int a);
ICSharpInterface^ MakeManaged();
};
Поскольку базовый класс определен в Native, я могу передать свою реализацию другому коду на native. Но сейчас я хочу проверить этот класс.
Если я использую #pragma make_public(Mixed);
это только сделает структуру общедоступной, без каких-либо функций, видимых извне.
Если я пытаюсь соединиться с dll смешанного режима из другой dll смешанного режима, я получаю ошибки компоновщика, потому что это собственный класс, и dll смешанного режима не генерирует .lib для ссылки.
И если я попытаюсь __declspec(dllexport)
класс, Visual Studio жалуется, потому что интерфейс предоставляет управляемые вещи.
Итак, мой вопрос:
Как мне создать экземпляр этого класса в своих тестах? Я был бы рад любому решению, которое показывает, как создать экземпляр, где я могу вызвать его открытый интерфейс, независимо от того, из C ++, C ++ / Cli или из C #.
Вы пропустили важный шаг, вы еще не рассматривали, как нативная программа собирается создать экземпляр смешанный объект. Что нетривиально, требует загрузки и инициализации CLR, чтобы он мог выполнять управляемый код. Имейте в виду, что клиентский код не делает это автоматически, он не знает bean-компоненты о CLR, он знает только о Native.dll. Есть три основных способа сделать это:
Сфокусируясь немного на последнем пункте, так как это то, что вам, вероятно, нравится, здесь вам нужно заводская функция, тот, который создает экземпляр смешанный class и возвращает Native * обратно вызывающей стороне. Так что он может вызвать ptr-> Add () и вызвать Mixed :: Add (). Это может выглядеть так:
extern "C" __declspec(dllexport)
Native* CreateObject() {
return new Mixed;
}
Также получает импорт .lib, который вы можете связать в своем родном проекте. Остерегайтесь недостатков, они значительны. Это не совсем быстро, так как заглушка должна проверить, инициализирована ли CLR, и выполнить переход от нативного к управляемому. Отчеты об ошибках чрезвычайно отвратительны, поскольку у вас нет приличного способа диагностировать исключения, которые генерируются в коде C #. А управление памятью является проблемой, вызывающая сторона должна быть в состоянии успешно уничтожить возвращенный объект, который требует, чтобы все модули использовали один и тот же CRT. Вид проблем, которые COM решает.
Точно такая же техника доступна и в C # с использованием переписывающего устройства IL. Gieseke-х неуправляемый экспорт Шаблон популярен.
Других решений пока нет …