Как узнать имя класса по идентификатору интерфейса (IID) в WinRT? - PullRequest
1 голос
/ 10 апреля 2019

У меня есть приложение XAML C ++ / WinRT на основе шаблона BlankApp. Создавая приложение, я понял, что мое приложение создает множество исключений за кулисами в моем окне вывода. Исключение, которое я пытаюсь понять, следующее:

Exception thrown at 0x00007FFA9EFA9149 (KernelBase.dll) in wzrd_editor.exe: WinRT originate error - 0x80040155 : 'Failed to find proxy registration for IID: {50F19C16-0A22-4D8E-A089-1EA9951657D2}.'.

То, что я делал, - это устранение ошибок при создании WinRT и просмотр стека вызовов. Однако мне интересно, как я могу определить имя класса IID, который показан в ошибке? Кажется, что было бы очень полезно узнать, чтобы выяснить источник этих исключений. Может быть, есть где-то в реестре, где я могу узнать?

Ответы [ 2 ]

2 голосов
/ 05 июля 2019

Основная проблема здесь заключается в том, что делегаты Xaml немного просты (делегаты, которые Xaml реализует для подписки на события, вызываемые приложением). Несмотря на то, что они действительно гибки, они не реализуют ни IAgileObject, ни IMarshal. Языковая проекция не может узнать что-либо о делегате без проверки, и это приводит к помехам в отладчике, хотя это вызвано не исключением, а скорее вызовом RoOriginateXxx.

C ++ / WinRT хранит только гибкие делегаты для обеспечения корректности квартиры. Затем он должен обойти это ограничение в реализации Xaml, сначала проверив, является ли делегат гибким (запросив IAgileObject). Если это не удается, он пытается создать гибкую ссылку (для размещения маршализируемых делегатов, таких как созданные в JavaScript). Если это не удается, он незаконно проникает в делегат, потому что другого выбора нет. Это последняя категория, которая поддерживает Xaml, но это означает, что отладчик сообщит об ошибке «Не удалось найти прокси-сервер для регистрации IID» для любого предоставленного Xaml делегата.

2 голосов
/ 26 апреля 2019

Вопрос объединяет два понятия: классы времени выполнения и интерфейсы. Классы времени выполнения - это именованные типы, которые реализуются через набор интерфейсов, некоторые из которых могут быть уникальными для класса, а другие могут быть реализованы во многих классах.

Для системных типов заголовки C ++ в SDK будут содержать определения для всех интерфейсов, общедоступных и приватных, и вы можете искать их по GUID для сопоставления с классом. Хотя иногда в реестре могут появляться и интерфейсы с именами, это не гарантируется.

Я сделал быстрый поиск, и я вижу, что интерфейс, упомянутый в ошибке, является Windows.UI.Xaml.IPropertyChangedEventHandler, который является базовым интерфейсом для делегата PropertyChangedEventHandler. Поскольку это является частью XAML, ожидается, что эти интерфейсы должны быть реализованы гибкими объектами и всегда должны вызываться в потоке пользовательского интерфейса.

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

Спасибо

Ben

...