У меня есть собственный C++ DLL, для которого я хотел бы иметь C++ / слой обертки CLI. Из того, что я понял, если бы Вы простой добавили C++ / класс CLI к проекту, то VS скомпилировал бы как смешанный режим, но я был, по-видимому, неправ, поскольку VS, кажется, даже не касается управляемого кода.
Так, учитывая существующую ранее собственную кодовую базу, что точно, пошаговый, необходимо сделать для создания смешанного режима DLL, так, чтобы я мог, может связаться в тот код с какого-либо языка.NET?
*Я должен сделать это, потому что мой собственный код использует классы C++, в которые я не могу P/Invoke.
Начните новый проект C ++ / CLI, а затем переместите в него свои собственные классы.
Ну, нет, это не будет смешанным режимом, пока вы не сообщите компилятору 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 не влиял на ваш существующий код, - это скомпилировать весь существующий код в собственную статическую библиотеку, а затем включить эту статическую библиотеку на этапе компоновки вашей библиотеки DLL C ++ / CLI.
Для файла проекта C ++ требуется параметр / clr. Я считаю, что это можно установить для всего проекта на общей вкладке или для отдельных файлов.
После указания параметра clr Visual Studio построит этот класс с помощью C ++ / CLI.
Если у вас есть исходный код 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-подобную функцию. Это тоже нормально.