C++/CLI Создание DLL в смешанном режиме

У меня есть родная C++ DLL, для которой я хотел бы иметь слой-обертку C++/CLI. Из того, что я понял, если бы вы просто добавили класс C++/CLI в проект, VS скомпилировал бы в смешанном режиме, но я был явно неправ, так как VS, похоже, даже не касается управляемого кода.

Итак, учитывая уже существующую базовую кодовую базу, что именно нужно делать шаг за шагом, чтобы создать DLL смешанного режима, чтобы я мог ссылаться на этот код с любого языка.NET?

* Мне нужно сделать это, потому что мой нативный код использует классы C++, в которые я не могу P/Invoke.

6 ответов

Ну, нет, это не будет режим смешивания, пока вы не скажете компилятору C++/CLI, что ваша старая DLL была написана в неуправляемом коде. Что должно было быть заметно, вы должны были получить ошибки компоновщика из неуправляемого экспорта DLL. Вам нужно использовать #pragma managed:

#pragma managed(push, off)
#include "oldskool.h"
#pragma comment(lib, "oldskool.lib")
#pragma managed(pop)

using namespace System;

public ref class Wrapper {
private:
    COldSkool* pUnmanaged;
public:
    Wrapper() { pUnmanaged = new COldSkool; }
    ~Wrapper() { delete pUnmanaged; pUnmanaged = 0; }
    !Wrapper() { delete pUnmanaged; }
    void sampleMethod() { 
        if (!pUnmanaged) throw gcnew ObjectDisposedException("Wrapper");
        pUnmanaged->sampleMethod(); 
    }
};

Хороший вариант предотвращения влияния /clr на существующий код - это скомпилировать весь существующий код в собственную статическую библиотеку, а затем включить эту статическую библиотеку на шаге соединения вашей библиотеки C++/CLI.

Начните новый проект C++/CLI, а затем перенесите в него ваши собственные классы.

Вместо того, чтобы включить "Общедоступную поддержку RunTime" на уровне проекта, можно включить ее для каждого файла отдельно, только взглянув на Свойства файла и перейдя к C / C++ | Генерал | Поддержка общего языка.

Это может упростить размещение вашего собственного кода и кода C++ / CLI в одном проекте, а не создавать отдельную C++/CLI DLL, просто содержащую оболочку, или использовать множество управляемых / неуправляемых прагм.

Так что просто сделайте это с классом оболочки C++/CLI .NET, который вы хотите написать.

Если у вас есть исходный код DLL с собственным C++, вы можете использовать управляемый C++ в смешанном режиме. В течение некоторого времени у Microsoft есть эталонный проект по миграции какой-либо известной игры DirectX на.NET. Один использовал управляемый C++ в смешанном режиме. Часть кода была переписана как управляемый код. Часть была вскоре изменена, чтобы быть скомпилированной как C++ в смешанном режиме, а часть была скомпилирована как код сборки (по соображениям производительности), но использовалась также непосредственно внутри управляемого кода как небезопасный код. В результате такого рода миграции достигается действительно очень хорошая производительность в конечном приложении. Таким образом, вы не тратите время на маршалинг между нативным и управляемым кодом. Маршалинг между безопасным и небезопасным управляемым кодом происходит очень быстро. Вероятно, вы должны также выбрать этот путь?

Другой способ вызова нативного кода из DLL внутри управляемого кода.NET хорошо известен. Каждая функция C++ имеет недекорированные имена (для просмотра используйте http://www.dependencywalker.com/). Если ваши C++ DLL экспортируют классы, а не C-подобные функции, эта DLL плохо спроектирована. Хорошо спроектированная DLL либо экспортирует C-подобные функции, либо экспортирует COM-интерфейсы. Если у вас есть такая "плохая" DLL и вы не хотите тратить время на написание COM, вы можете легко написать еще одну DLL, которая будет играть роль заглушки. Эта DLL импортирует все классы C++ (см. http://msdn.microsoft.com/en-us/library/81h27t8c.aspx, Экспорт класса C++ из DLL и http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx например) из "плохой" DLL и экспортировать C-подобную функцию. С этим тоже все в порядке.

Файл проекта C++ нуждается в параметре /clr. Полагаю, это можно установить для всего проекта на вкладке "Общие" или установить для отдельных файлов.

После указания параметра clr Visual Studio создаст этот класс с использованием C++/CLI.

Другие вопросы по тегам