Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Сведения об установке и использовании расширения Visual Studio C++/WinRT (VSIX) (которое обеспечивает поддержку шаблонов проектов) см. в статье Поддержка C++/WinRT в Visual Studio.
Эта тема вынесена в начало, чтобы вы сразу были о ней в курсе, даже если она вам пока не нужна. Приведённая ниже таблица симптомов неполадок и способов их устранения может быть полезна независимо от того, пишете ли вы новый код или переносите существующее приложение. Если вы переносите проект и хотите побыстрее продвинуться до этапа, на котором он собирается и запускается, то можете временно продвинуться, закомментировав или заменив заглушками любой некритичный код, который вызывает проблемы, а затем позже вернуться и устранить этот технический долг.
Список часто задаваемых вопросов см. в разделе часто задаваемые вопросы.
Отслеживание проблем XAML
Исключения синтаксического анализа XAML могут быть сложными для диагностики, особенно если в исключении нет значимых сообщений об ошибках. Убедитесь, что отладчик настроен для перехвата исключений первого шанса (чтобы попытаться и поймать исключение синтаксического анализа на ранней стадии). Вы можете проверить переменную исключения в отладчике, чтобы определить, имеет ли HRESULT или сообщение любую полезную информацию. Кроме того, проверьте окно вывода Visual Studio для вывода сообщений об ошибках с помощью средства синтаксического анализа XAML.
Если приложение завершает работу и единственное, что вам известно, — это то, что во время синтаксического анализа разметки XAML возникло необработанное исключение, то это может быть результатом ссылки (по ключу) на отсутствующий ресурс. Или это может быть исключение, созданное внутри UserControl, настраиваемого элемента управления или настраиваемой панели макета. Крайняя мера — бинарное разделение. Удалите около половины разметки на странице XAML и повторно запустите приложение. Затем вы узнаете, находится ли ошибка где-то в половине, которую вы удалили (которая теперь должна восстановиться в любом случае) или в половине, которую вы не удалили. Повторяйте процесс, разделяя пополам ту часть, которая содержит ошибку, и так далее, пока точно не определите источник проблемы.
Симптомы и средства правовой защиты
| Симптом | Средство |
|---|---|
| Во время выполнения выдается исключение со значением HRESULT, равным REGDB_E_CLASSNOTREGISTERED. | См. раздел "Почему я получаю исключение "класс не зарегистрирован"?. |
| Компилятор C++ создает ошибку "implements_type": не является членом любого прямого или косвенного базового класса проецируемого< типа>". | Это может произойти, если вы вызываете make, используя имя вашего типа реализации без указания пространства имён (MyRuntimeClass, например), и не включили файл заголовка для этого типа. Компилятор интерпретирует MyRuntimeClass как проецируемый тип. Решение заключается в том, чтобы включить заголовок для типа реализации (MyRuntimeClass.hнапример. |
| Компилятор C++ создает ошибку "попытка ссылаться на удаленную функцию". | Это может произойти, когда вы вызываете make, а тип реализации, который вы передаёте в качестве параметра шаблона, имеет = delete конструктор по умолчанию. Измените файл заголовка типа реализации и измените его = delete на = default. Вы также можете добавить конструктор в IDL для класса среды выполнения. |
| Вы реализовали INotifyPropertyChanged, но привязки XAML не обновляются (и интерфейс не подписывается на PropertyChanged). | Не забудьте задать Mode=OneWay (или TwoWay) в выражении привязки в разметке XAML. См. элементы управления XAML; привязка к свойству C++/WinRT. |
| Вы привязываете элемент управления элементами XAML к наблюдаемой коллекции, и исключение создается во время выполнения с сообщением "Параметр является неверным". | В файле IDL и в реализации объявляйте любую наблюдаемую коллекцию в виде типа Windows.Foundation.Collections.IVector<IInspectable>. Но возвращайте объект, реализующий Windows.Foundation.Collections.IObservableVector<T>, где T — это тип элементов. См. элементы управления XAML; привязка к коллекции C++/WinRT. |
| Компилятор C++ создает ошибку формы "'MyImplementationType_base<MyImplementationType>': нет подходящего конструктора по умолчанию". | Это может произойти, если вы унаследовали класс от типа с нетривиальным конструктором. Конструктор производного типа должен передавать параметры, необходимые конструктору базового типа. Пример см. в разделе Наследование от типа с нетривиальным конструктором. |
| Компилятор C++ выдает ошибку "не удается преобразовать тип "const std::vector<std::wstring,std::allocator<_Ty>>" в "const winrt::param::async_iterable<winrt::hstring> &'"". | Это может произойти при передаче объекта std::vector |
| Компилятор C++ выдает ошибку "не удается преобразовать из 'const std::vector<winrt::hstring,std::allocator<_Ty>>' в 'const winrt::param::async_iterable<winrt::hstring> &'". | Это может произойти при передаче std::vector winrt::hstring в асинхронный api среда выполнения Windows, который ожидает коллекцию, и вы не скопировали и не переместили вектор в асинхронный вызывающий объект. Дополнительные сведения см. в разделе Стандартные типы данных C++ и C++/WinRT. |
| При открытии проекта Visual Studio выдает ошибку "Приложение для проекта не установлено". | Если вы еще не сделали этого, необходимо установить шаблоны C++ Windows App SDK И расширение C++/WinRT Visual Studio (VSIX) (см. Visual Studio поддержку C++/WinRT). |
| Тесты комплекта сертификации приложение для Windows создают ошибку, что один из классов среды выполнения "не является производным от базового класса Windows. Все составные классы должны в конечном счете быть производными от типа в пространстве имен Windows". | Любой класс среды выполнения (объявленный в приложении), производный от базового класса, называется составным классом. Конечный базовый класс компонуемого класса должен быть типом, происходящим из пространства имен Windows.* или Microsoft.*; например, Microsoft.UI.Xaml.DependencyObject. Дополнительные сведения см. Элементы управления XAML; привязка к свойству C++/WinRT. |
| Компилятор C++ создает ошибку "T должен быть типом WinRT" для специализации делегата EventHandler или TypedEventHandler. | Рассмотрите возможность использовать winrt::delegate<...T> вместо этого. См. События авторов в C++/WinRT. |
| Компилятор C++ создает ошибку "Тип T должен быть типом WinRT" для специализации асинхронной операции среда выполнения Windows. | Вместо этого рассмотрите возможность возврата объекта task из Parallel Patterns Library (PPL). См. статью "Параллелизм" и асинхронные операции. |
| Компилятор C++ создает ошибку "Тип T должен быть типом WinRT" при вызове winrt::xaml_typename. | Используйте проецируемый тип с winrt::xaml_typename (например, используйте BgLabelControlApp::BgLabelControl), а не тип реализации (например, не используйте BgLabelControlApp::implementation::BgLabelControlControl). См. настраиваемые элементы управления XAML (шаблон). |
| Компилятор C++ создает сообщение об ошибке C2220: предупреждение, обработанное как ошибка, — файл "object" не создан. | Исправьте предупреждение или задайте для C/C++>Общие>Считать предупреждения ошибками значение Нет (/WX-). |
| Приложение завершает работу, так как обработчик событий в объекте C++/WinRT вызывается после уничтожения объекта. | См. раздел "Безопасный доступ к этому указателю" с делегатом обработки событий. |
| Компилятор C++ создает ошибку C2338: это только для слабой поддержки ссылок. | Вы запрашиваете слабую ссылку для типа, который передал маркерную структуру winrt::no_weak_ref в качестве аргумента шаблона своему базовому классу. См. раздел "Отказ от слабой поддержки ссылок". |
| Компилятор C++ создает "consume_Something: функция, возвращающая "авто", не может использоваться до его определения". | См. C3779: Почему компилятор выдает ошибку "consume_Something: функцию, возвращающую 'auto', нельзя использовать до ее определения"? |
| Компоновщик C++ выдает сообщение об ошибке "error LNK2019: неразрешенный внешний символ" | См. статью "Почему компоновщик дает мне ошибку "LNK2019: неразрешенный внешний символ"?. |
| Цепочка инструментов LLVM и Clang создает ошибки при использовании с C++/WinRT. | Мы не поддерживаем цепочку инструментов LLVM и Clang для C++/WinRT, но если вы хотите эмулировать ее внутренне, то можно попробовать эксперимент, например описанный в разделе "Можно ли использовать LLVM/Clang для компиляции с помощью C++/WinRT?". |
| Компилятор C++ создает "недоступен соответствующий конструктор по умолчанию" для проецируемого типа. | Если вы пытаетесь отложить инициализацию объекта класса среды выполнения или использовать и реализовать класс среды выполнения в том же проекте, необходимо вызвать конструктор std::nullptr_t . Дополнительные сведения см. в разделе "Использование API с помощью C++/WinRT". |
| Компилятор C++ создает ошибку C3861: "from_abi": идентификатор не найден" и другие ошибки, возникающие в base.h. Вы можете увидеть эту ошибку, если используете Visual Studio 2017 (версия 15.8.0 или более поздняя) и используете Windows SDK версии 10.0.17134.0 (Windows 10, версия 1803) в качестве целевой платформы. | Либо выберите более позднюю (лучше соответствующую стандарту) версию Windows SDK, либо задайте для свойства проекта C/C++>Language>Conformance mode: No (также, если /permissive- присутствует в свойстве проекта C/C++>Language>Command Line в разделе Additional Options, удалите его). |
| Компилятор C++ создает ошибку C2039: "IUnknown": не является членом глобального пространства имен". | Узнайте, как перенацелить проект C++/WinRT на более позднюю версию пакета SDK Windows. |
| Компоновщик C++ создает ошибку LNK2019: неразрешенный внешний символ _WINRT_CanUnloadNow@0, на который ссылается функция _VSDesignerCanUnloadNow@0". | Узнайте, как перенацелить проект C++/WinRT на более позднюю версию пакета SDK Windows. |
| Процесс сборки выдает сообщение об ошибке C++/WinRT VSIX больше не поддерживает сборку проектов. Добавьте ссылку на пакет NuGet Microsoft.Windows.CppWinRT. | Установите пакет NuGet Microsoft.Windows.CppWinRT в ваш проект. Дополнительные сведения см. в более ранних версиях расширения VSIX. |
| Компоновщик C++ выдает ошибку LNK2019: неразрешенный внешний символ, в которой упоминается winrt::impl::consume_Windows_Foundation_Collections_IVector. | Начиная с C++/WinRT 2.0, если вы используете for с диапазонным циклом для коллекции среда выполнения Windows, вам теперь потребуется #include <winrt/Windows.Foundation.Collections.h>. |
| Компилятор C++ выдает сообщение об ошибке «ошибка C4002: слишком много аргументов при вызове функциональноподобного макроса GetCurrentTime». | Узнайте , как устранить неоднозначность с помощью GetCurrentTime и (или) TRY?. |
| Компилятор C++ выдает сообщение "ошибка C2334: непредвиденная лексема(ы) перед "{"; пропуск предполагаемого тела функции". | Узнайте , как устранить неоднозначность с помощью GetCurrentTime и (или) TRY?. |
| Компилятор C++ выдает сообщение "winrt::impl::produce<D,I> не удается создать экземпляр абстрактного класса из-за отсутствия GetBindingConnector". | Вам нужно #include <winrt/Microsoft.UI.Xaml.Markup.h>. |
| Компилятор C++ выдаёт ошибку C2039: "promise_type": не является членом "std::experimental::coroutine_traits<void>". | Ваша корутина должна возвращать либо объект асинхронной операции, либо winrt::fire_and_forget. См. статью "Параллелизм" и асинхронные операции. |
| В вашем проекте возникает "неоднозначный доступ к 'PopulatePropertyInfoOverride'". | Эта ошибка может возникать при объявлении одного базового класса в IDL и другом базовом классе в разметке XAML. |
| При первой загрузке решения C++/WinRT появляется сообщение "Сбой сборки на этапе разработки для проекта 'MyProject.vcxproj' с конфигурацией 'Debug|x86'. IntelliSense может быть недоступен.". | Эта проблема IntelliSense будет устранена после первой сборки. |
| Попытка указать winrt::auto_revoke при регистрации делегата приводит к возникновению исключения winrt::hresult_no_interface. | См. Если не удается зарегистрировать делегат автоматического отзыва. |
| В приложении C++/WinRT при использовании компонента C# среда выполнения Windows, использующего XAML, компилятор создает ошибку формы "MyNamespace_XamlTypeInfo": не является членом winrt::MyNamespace", где MyNamespace является именем пространства имен среда выполнения Windows компонента. | В приложении C++/WinRT, использующем этот компонент, в pch.h добавьте #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> — заменив MyNamespace соответствующим образом. |
| В проекте C++/WinRT в Visual Studio IntelliSense выдает ошибку вида "error E1696: не удается открыть исходный файл". | Скомпилируйте созданный проект по крайней мере один раз. Затем щелкните правой кнопкой мыши в редакторе исходного кода >Повторно сканировать>Повторно сканировать файл. Это позволит устранить все ошибки IntelliSense, включая E1696. |
Note
Если этот раздел не ответил на ваш вопрос, вы можете найти помощь, перейдя в сообщество разработчиков Visual Studio C++ или используя c++-winrt тег в Stack Overflow.
Связанные темы
Note
Многие разделы C++/WinRT находятся в процессе переноса из документации по UWP в этот раздел. Пока миграция не завершится, ссылки в приведенном ниже списке могут привести к разделу документации UWP. Проекция языка C++/WinRT одинакова для приложений UWP и WinUI 3, поэтому содержимое применимо в обоих контекстах. Все шаблоны, относящиеся к UWP (например, жизненный цикл приложения или Windows.UI API пространства имен), явно отмечены в этих статьях.
Windows developer