Использование смешанных DLL из / clr: pure projects - PullRequest
1 голос
/ 15 ноября 2008

Я строю проект вместе с Dll.

Dll должен поддерживать собственный код, поэтому я объявил его как / clr. Мой проект изначально был также / clr, и все было хорошо. Однако я хотел бы включить некоторые тесты NUnit, поэтому мне пришлось переключить мой основной проект с / clr на /clr:pure.

Все по-прежнему компилируется, но любой вызов Dll вызывает ошибку во время выполнения. Когда я возвращаюсь обратно к / clr, все в порядке

В моей Dll экспортируемые функции объявлены следующим образом:

#define DllExport   __declspec( dllexport )
DllExport bool DisplayScan(bool bShow, bool bAllPasses) { }

Я также создал файл .def, содержащий реальные имена всех экспортируемых функций

LIBRARY "Controller"
EXPORTS
DisplayScan

Из моего основного проекта мой импорт объявлен следующим образом:

#define _DllImport [DllImport("Controller.dll", CallingConvention = CallingConvention::Cdecl)] static
_DllImport bool DisplayScan(bool bShow, bool bAllPasses)

Кто-нибудь когда-либо сталкивался с такой проблемой?

Ответы [ 4 ]

3 голосов
/ 15 ноября 2008

В основном вы делаете что-то, что не поддерживается; / clr: чистый и собственный экспорт DLL. Как указано в этой статье MSDN"чистые сборки не могут экспортировать функции, которые можно вызывать из собственных функций, поскольку точки входа в чистую сборку используют соглашение о вызовах __clrcall."

Я не уверен в лучшем обходном пути. Однако, немного поэкспериментировав, возможно, вы сможете воспользоваться соглашением о вызовах __clrcall с параметром / clr. Вот ссылка , которая может быть полезна. Из того, что я могу собрать, вы сможете экспортировать эти управляемые классы и использовать их в управляемой сборке, такой как ваш управляемый тестовый проект NUnit, но сохраняйте там свои неуправляемые экспорты с различными сигнатурами методов. Имейте в виду, что как только вы предоставляете любой класс .net через экспорт, ему нужно будет использовать соглашение о вызовах __clrcall.

3 голосов
/ 15 ноября 2008

Хорошо, теперь все работает

Фактически, это работало с самого начала.

Мораль: не пытайтесь бросить символ * в std :: string

Странная вещь: все нормально в / clr, пока вы не вернетесь из функции. Он сразу падает в / clr: pure

1 голос
/ 04 мая 2012

Преимущества / clr: pure

Лучшая производительность: поскольку чистые сборки содержат только MSIL, нет собственных функций, и поэтому нет необходимости в управляемых / неуправляемых переходах. (Вызовы функций, выполняемые через P / Invoke, являются исключением из этого правила.)

Осведомленность о домене приложений: управляемые функции и типы данных CLR существуют внутри доменов приложений, что влияет на их видимость и доступность. Чистые сборки учитывают домен (__declspec (appdomain) подразумевается для каждого типа), поэтому доступ к их типам и функциям из других компонентов .NET проще и безопаснее. В результате чистые сборки легче взаимодействуют с другими компонентами .NET, чем смешанные сборки.

Загрузка не на диск: чистые сборки можно загружать в память и даже передавать в потоковом режиме. Это важно для использования сборок .NET в качестве хранимых процедур. Это отличается от смешанных сборок, которые из-за зависимости от механизмов загрузки Windows должны существовать на диске для выполнения.

Отражение: Невозможно отразить поверх смешанных исполняемых файлов, в то время как чистые сборки обеспечивают полную поддержку отражения. Для получения дополнительной информации см. Reflection (C ++ / CLI).

Управляемость хоста: поскольку чистые сборки содержат только MSIL, они ведут себя более предсказуемо и гибко, чем смешанные сборки, когда используются в приложениях, в которых размещается CLR, и изменяют поведение по умолчанию.

Ограничения / clr: pure

В этом разделе описаны функции, которые в настоящее время не поддерживаются /clr:pure.

.

Чистые сборки не могут быть вызваны неуправляемыми функциями. Поэтому чистые сборки не могут реализовывать интерфейсы COM или предоставлять собственные обратные вызовы. Чистые сборки не могут экспортировать функции через файлы __declspec (dllexport) или .DEF. Кроме того, функции, объявленные с соглашением __clrcall, не могут быть импортированы через __declspec (dllimport). Функции в собственном модуле можно вызывать из чистой сборки, но чистые сборки не могут предоставлять функции, которые можно вызывать самостоятельно, поэтому раскрытие функциональности в чистой сборке должно выполняться через управляемые функции в смешанной сборке. Дополнительные сведения см. В разделе Как выполнить миграцию в / clr: pure (C ++ / CLI).

библиотеки ATL и MFC не поддерживаются компиляцией в чистом режиме в Visual C ++.

Чистые .net-модули не принимаются в качестве входных данных для компоновщика Visual C ++. Однако чистые файлы .obj принимаются компоновщиком, а файлы .obj содержат расширенный набор информации, содержащейся в сетевых модулях. Для получения дополнительной информации см. Файлы .netmodule как входные данные компоновщика.

Поддержка COM компилятора (#import) не поддерживается, так как это приведет к неуправляемым инструкциям в чистой сборке.

Параметры с плавающей точкой для выравнивания и обработки исключений не регулируются для чистых сборок. В результате, __declspec (align) не может быть использован. Это делает некоторые заголовочные файлы, такие как fpieee.h, несовместимыми с /clr:pure.

Функция GetLastError в PSDK может давать неопределенное поведение при компиляции с /clr:pure.

0 голосов
/ 09 сентября 2009

ваша проблема заключается в вызове ConventionCallingConvention = CallingConvention :: Cdecl ... определите вашу функцию так или используйте stdcall или clrcall, clecl для чистого C

или проблема здесь: определить эту функцию extern не статично

...