Создание DLL в смешанном режиме С++/CLI
У меня есть родная С++ DLL, для которой я хотел бы иметь оберточный слой С++/CLI. Из того, что я понял, если вы просто добавили класс С++/CLI в проект, VS будет компилироваться как смешанный режим, но я, по-видимому, ошибался, поскольку VS, похоже, даже не касается управляемого кода.
Итак, учитывая предварительно существующую собственную базовую базу кода, что именно, поэтапно, вам нужно сделать для создания DLL смешанного режима, чтобы я мог подключиться к этому коду с любого языка .NET?
* Мне нужно сделать это, потому что мой собственный код использует классы С++, которые я не могу выполнить P/Invoke.
Ответы
Ответ 1
Ну, нет, он не может быть смешанным, пока вы не сообщите компилятору С++/CLI, что ваша устаревшая DLL была написана в неуправляемом коде. Что должно было быть заметно, вы должны были получить ошибки компоновщика из неуправляемого экспорта DLL. Вам нужно использовать управляемый #pragma:
#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();
}
};
Ответ 2
Хорошим вариантом предотвращения /clr от влияния на ваш существующий код является компиляция всего существующего кода в собственную статическую библиотеку, а затем включение этой статической библиотеки на этапе ссылки вашей DLL С++/CLI.
Ответ 3
Начните новый проект С++/CLI, а затем переместите в него свои родные классы.
Ответ 4
Вместо того, чтобы включить поддержку "Common Language RunTime Support" на уровне проекта, ее можно включить в файл за файлом, только просмотрев свойства файла и перейдя на C/С++ | Общий | Поддержка общего языка.
Это может облегчить использование вашего родного и С++/CLI-кода в одном проекте, а не создание отдельной библиотеки С++/CLI, содержащей только оболочку, или использование множества управляемых/неуправляемых прагм.
Так просто сделайте это в классе оболочки С++/CLI.NET, который вы хотите написать.
Ответ 5
Если у вас есть исходный код DLL с родным С++, вы можете использовать управляемый С++ в смешанном режиме. Microsoft в течение некоторого времени ссылается на проект миграции какой-то известной игры DirectX на .NET. Один использовал управляемый С++ в смешанном режиме. Часть кода была переписана как управляемый код. Часть была вскоре изменена, чтобы быть скомпилированной как С++ в смешанном режиме, и часть была скомпилирована как код сборки (из-за причины производительности), но также использовалась также непосредственно внутри управляемого кода как небезопасный код. Такая миграция в результате приводит к очень хорошей производительности в конечном приложении. Таким образом, вы не тратите время на маршалинг между собственным и управляемым кодом. Марширование между безопасным и небезопасным управляемым кодом происходит очень быстро. Возможно, вы также должны выбрать этот способ?
Другой способ вызова собственного кода из DLL внутри управляемого кода .NET хорошо известен. Каждая функция С++ имеет неподтвержденные имена (используйте http://www.dependencywalker.com/, чтобы увидеть там). Если ваши классы экспорта С++ DLL, а не C-подобные функции, эта DLL плохо разработана. Хорошо спроектированная DLL либо экспортирует C-подобные функции, либо экспортирует COM-интерфейсы. Если у вас есть такая "плохая" DLL и вы не хотите тратить время на создание COM, вы можете легко написать еще одну DLL, которая будет играть роль заглушки. Эта DLL импортирует все классы С++ (см. http://msdn.microsoft.com/en-us/library/81h27t8c.aspx, Экспорт класса С++ из библиотеки DLL и http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx например) из "плохой" DLL и экспортировать C-подобную функцию. Этот путь также в порядке.
Ответ 6
Файл проекта С++ нуждается в опции /clr. Это можно установить для всего проекта на общей вкладке, я полагаю, или установить для отдельных файлов.
Как только опция clr указана, Visual Studio построит этот класс с использованием С++/CLI.