C ++ / CLI Создание DLL в смешанном режиме - PullRequest
13 голосов
/ 22 апреля 2010

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

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

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

Ответы [ 6 ]

18 голосов
/ 22 апреля 2010

Ну, нет, это не будет режим смешивания, пока вы не скажете компилятору 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(); 
    }
};
6 голосов
/ 24 апреля 2010

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

2 голосов
/ 22 апреля 2010

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

1 голос
/ 13 марта 2012

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

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

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

0 голосов
/ 22 апреля 2010

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

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

0 голосов
/ 22 апреля 2010

Если у вас есть исходный код 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-подобную функцию. С этим тоже все в порядке.

...