Поделиться через


Практическое руководство. Миграция в /clr:pure (C++/CLI)

В этом разделе рассматриваются вопросы, которые могут возникнуть во время осуществления миграции в чистый MSIL с помощью /clr:pure (дополнительные сведения см. в разделе /clr (компиляция CLR)). Раздел подразумевает, что подвергаемый миграции код был скомпилирован как смешанная сборка с помощью параметра /clr, так как прямого пути миграции из неуправляемого кода в чистый MSIL не существует.Дополнительные сведения о неуправляемом коде см. в разделе Практическое руководство. Переход на /clr перед осуществлением миграции в чистый MSIL.

Основные изменения

Чистый MSIL состоит из инструкций MSIL, поэтому код с функциями, которые нельзя реализовать средствами MSIL, не скомпилируется.Это касается и функций, использующих соглашения о вызовах, отличные от __clrcall(функции, отличные от __clrcall могут вызываться в компоненте чистого MSIL, но не определяться).

Чтобы избежать ошибок в среде выполнения, активируйте предупреждение C4412.Активируйте предупреждение C4412, добавив #pragma warning (default : 4412) в каждую единицу компиляции, которая компилируется с /clr:pure и передает типы C++ в IJW (/clr)) или машинный код и вызывает их обратно.Дополнительные сведения см. в разделе Предупреждение компилятора (уровень 2) C4412.

Архитектурные вопросы

Некоторые ограничения сборок, использующих чистый MSIL, перечисленные в разделе Чистый и проверяемый код (C++/CLI), порождают последствия высокого уровня при разработке стратегий разработки приложения и миграции.Следует отметить, что в отличие от смешанных сборок, сборки чистого MSIL не совместимы с неуправляемыми модулями полностью.

Сборки чистого MSIL могут вызывать неуправляемые функции, но не могут вызываться управляемыми функциями.В результате, чистый MSIL является лучшим решением для клиентского кода, который использует неуправляемые функции, чем для кода сервера, используемого неуправляемыми функциями.Если функциональность, которая содержится в сборке чистого MSIL, используется неуправляемой функцией, то смешанная сборка должна применяться как уровень интерфейса.

Приложения, которые используют ATL или MFC, не являются удобными решениями для миграции в чистый MSIL, поскольку данные библиотеки не поддерживаются в этой версии.Таким же образом, Windows SDK содержат файл заголовка, который не компилируется с /clr:pure.

Хотя сборки чистого MSIL и могут вызывать неуправляемые функции, подобная способность ограничена простыми функциями C-типа.Использование более сложных неуправляемых API, вероятно, потребует предоставления неуправляемой функциональности в виде COM-интерфейса или смешенной сборки, которая может служить как интерфейс между чистым MSIL и неуправляемыми компонентами.Единственный путь для применения неуправляемой функции – это использование слоя смешанной сборки. В этом случае функция выполняет обратный вызов. Например, чистая сборка может предоставлять собственную вызываемую функцию для использования обратного вызова.

Домены приложения и соглашения о вызове

Несмотря на то, что сборки чистого MSIL могут использовать неуправляемую функцию, функции и статистические данные обрабатываются по-разному.В чистых сборках функции реализуются с соглашением о вызове __clrcall, а статистические данные хранятся по доменам приложений.Эта отличается от заданного поведения по умолчанию в неуправляемых и смешанных сборках, которые используют соглашение о вызове __cdecl в функциях и хранят статические данные по процессам.

В рамках контекста чистого MSIL (и проверяемого кода, скомпилированного с /clr:safe) значения по умолчанию не представляют сложности, поскольку __clrcall является соглашением о вызове по умолчанию в среде CLR, а домены приложений — собственной областью для статистических и глобальных данных приложений .NET.Однако во время взаимодействия с неуправляемыми или смешанными компонентами разная обработка функций и глобальных данных может вызвать проблемы.

Например, если компонент чистого MSIL вызывает функцию в неуправляемой или смешанной библиотеке DLL, файл заголовка DLL используется для компиляции чистой сборки.Тем не менее, пока соглашение о вызове для каждой функции в заголовке не будет явно обозначено, всем функциям будет присваиваться __clrcall.Впоследствии это приведет к ошибкам во время выполнения, поскольку функции, скорее всего, будут реализованы вместе с соглашением __cdecl.Функции в неуправляемом файле заголовка должны быть явно обозначены как __cdecl, или же весь исходный код библиотеки DLL должен быть перекомпилирован с /clr:pure.

Аналогичным образом указатели функции предполагают наличие указателя на функции __clrcall в случае компиляции с /clr:pure.Указатели должны явно отмечаться правильным соглашением о вызове.

Дополнительные сведения см. в разделе Домены приложений и Visual C++.

Ограничения компоновки

Компоновщик Visual C++ не соединяет смешанные и чистые OBJ-файлы, поскольку область хранения и соглашения о вызове не совпадают.

См. также

Ссылки

Чистый и проверяемый код (C++/CLI)