Как я могу определить имя класса по идентификатору интерфейса (IID) в WinRT?

У меня есть приложение 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, которое отображается в ошибке? Похоже, это было бы очень полезно знать, чтобы выяснить источник этих исключений. Может есть где в реестре узнать?


person mbl    schedule 10.04.2019    source источник


Ответы (2)


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

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

person Kenny Kerr    schedule 05.07.2019

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

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

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

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

Спасибо,

Бен

person Ben Kuhn    schedule 26.04.2019