В начале этой недели Кенни Керр представил C ++ / WinRT на CppCon 20161. Это стандартная проекция C ++ для среды выполнения Windows, основанная на Современный.
Насколько я понимаю, C ++ / CX компилятор / препроцессор / генератор кода не касается стандартного кода C ++, и поскольку C ++ / WinRT является стандартной библиотекой C ++, я считаю наивной интерпретацией того, что и C ++ / CX, и C ++ / WinRT могут использоваться в одном проекте.
Вопросы:
В случае, если это имеет значение, ответы на эти вопросы позволяют мне сейчас принимать решения о том, как перенести мои проекты C ++ / CX в будущее.
1 Использование стандарта C ++ для среды выполнения Windows (на YouTube).
Относительно вопроса «Может ли C ++ / WinRT потреблять типы, реализованные с C ++ / CX в том же проекте?»
Ответ «Да» и «Нет». Поскольку «ref class» определен в том же проекте, так как такой проект должен быть скомпилирован с включенным C ++ / CX, ваш код может просто использовать этот класс, как и любой ref-класс.
Тем не менее, если вы хотите использовать ‘ref class’ в качестве проекции C ++ / WinRT, ответ фактически будет отрицательным.
Чтобы получить прогнозируемое определение класса C ++ / WinRT, вам нужно запустить компилятор cppwinrt.exe над метаданными для ‘ref class’. Это потребует как-то получения метаданных. Вы можете настроить какой-то механизм для компиляции ‘ref-класса’ один раз, получить winmd, обработать его через mdmerge, чтобы привести его в каноническую форму, запустить cppwinrt.exe для метаданных, чтобы получить определение прогнозируемого класса, а затем включить сгенерированные заголовки.
Кроме того, вы можете написать IDL для описания «класса ref», скомпилировать его в метаданные с помощью MIDLRT, а затем запустить cppwinrt.exe. Ни один из них не является практичным ИМО.
Наиболее разумная альтернатива — просто использовать класс ref как тип C ++ / CX, поскольку определение находится в том же решении. Следующее наиболее практичное решение — поместить класс в отдельный проект, скомпилировать его, получив winmd, а затем создать заголовки из winmd. Этот подход также позволяет создавать отдельный проект, который использует ‘ref class’ (через проекцию) без использования кода C ++ / CX.
Чтобы быть полностью прозрачным, обратите внимание, что наш первоначальный выпуск (теперь доступен на https://github.com/Microsoft/cppwinrt) не включает сам компилятор cppwinrt.exe. Скорее, он содержит заголовочные файлы C ++ / WinRT, содержащие проекции для всех типов / API среды выполнения Windows, определенных в Windows 10 Anniversary Update SDK — это включает в себя API универсальной платформы и все API расширения SDK.
Короткий ответ: да C ++ / CX и C ++ / WinRT может быть использован в том же проекте.
Компилятор C ++ / CX внедряет типы Winmd в корневое пространство имен. C ++ / WinRT оборачивает все внутри своего корневого пространства имен winrt, чтобы обеспечить взаимодействие с C ++ / CX и избежать ошибок неоднозначности компилятора C ++ с другими библиотеками. Итак, следующий код C ++ / CX:
using namespace Windows::Foundation;
using namespace Windows::Networking;
Uri ^ uri = ref new Uri(L"https://moderncpp.com/");
HostName ^ name = ref new HostName(L"moderncpp.com");
Может быть переписан с C ++ / WinRT следующим образом:
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Networking;
Uri uri(L"https://moderncpp.com/");
HostName name(L"moderncpp.com");
В качестве альтернативы, если вы компилируете с / ZW, вы можете переписать его следующим образом (чтобы избежать ошибки C2872: «Windows»: неоднозначный символ):
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Networking;
Uri uri(L"https://moderncpp.com/");
HostName name(L"moderncpp.com");
Другой способ объединить C ++ / CX и C ++ / WinRT в одном и том же исходном файле — это использовать корневое пространство имен для обоих:
namespace cx
{
using namespace Windows::Foundation;
using namespace Windows::Networking;
}
namespace winrt
{
using namespace Windows::Foundation;
using namespace Windows::Networking;
}
void Sample()
{
cx::Uri uri(L"https://moderncpp.com/");
winrt::HostName name(L"moderncpp.com");
}
В конце концов, C ++ / WinRT — это просто стандартная библиотека C ++, которую вы можете включить в любой применимый проект C ++. Однако C ++ / CX и C ++ / WinRT работают с метаданными по-разному. C ++ / CX одновременно использует и генерирует метаданные, тогда как C ++ / WinRT ограничен стандартным C ++ и, таким образом, требует отдельного инструмента (cppwinrt.exe), который поможет преодолеть этот разрыв.