Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++/WinRT can't easily add a UserControl from a C# Windows Runtime Component #5040

Closed
michael-hawker opened this issue May 18, 2021 · 6 comments
Labels

Comments

@michael-hawker
Copy link
Collaborator

Refiled from microsoft/cppwinrt#943 as per @kennykerr

(This issue is about OS UWP, but seems similar/related to discussions around WinUI 3 as well in #4907.)

Was following this guide: https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/use-csharp-component-from-cpp-winrt (still running in Debug though)

But instead of trying to create a regular class, was trying to create a UserControl component to use in XAML. That would produce these build errors:

1>Generated Files\XamlTypeInfo.g.cpp(270,74): error C2039: 'CSharpIslandRuntimeComponent_XamlTypeInfo': is not a member of 'winrt::CSharpIslandRuntimeComponent'
1>Generated Files\XamlTypeInfo.g.cpp(270,74): error C3083: 'CSharpIslandRuntimeComponent_XamlTypeInfo': the symbol to the left of a '::' must be a type
1>Generated Files\XamlTypeInfo.g.cpp(270,117): error C2039: 'XamlMetaDataProvider': is not a member of 'winrt::CSharpIslandRuntimeComponent'
1>Generated Files\XamlTypeInfo.g.cpp(270,137): error C2259: 'winrt::CppWinRTToolkitIsland::implementation::XamlMetaDataProvider': cannot instantiate abstract class
1>Generated Files\XamlTypeInfo.g.cpp(271,74): error C2039: 'CSharpIslandRuntimeComponent_XamlTypeInfo': is not a member of 'winrt::CSharpIslandRuntimeComponent'
1>Generated Files\XamlTypeInfo.g.cpp(271,74): error C3083: 'CSharpIslandRuntimeComponent_XamlTypeInfo': the symbol to the left of a '::' must be a type
1>Generated Files\XamlTypeInfo.g.cpp(271,117): error C2039: 'XamlMetaDataProvider': is not a member of 'winrt::CSharpIslandRuntimeComponent'
1>Generated Files\XamlTypeInfo.g.cpp(271,137): error C2259: 'winrt::CppWinRTToolkitIsland::implementation::XamlMetaDataProvider': cannot instantiate abstract class

In Release with .NET Native there are fewer of these errors at build:

2>Generated Files\XamlTypeInfo.g.cpp(270,74): error C2039: 'CSharpIslandRuntimeComponent_XamlTypeInfo': is not a member of 'winrt::CSharpIslandRuntimeComponent'
2>Generated Files\XamlTypeInfo.g.cpp(270,74): error C3083: 'CSharpIslandRuntimeComponent_XamlTypeInfo': the symbol to the left of a '::' must be a type
2>Generated Files\XamlTypeInfo.g.cpp(270,117): error C2039: 'XamlMetaDataProvider': is not a member of 'winrt::CSharpIslandRuntimeComponent'

To get the C++/WinRT project to compile I additionally added the Xaml Type Info header to the MainPage.h file as well (as mentioned in this Stack Overflow):

#include "winrt/CSharpIslandRuntimeComponent.h"
#include "winrt/CSharpIslandRuntimeComponent.CSharpIslandRuntimeComponent_XamlTypeInfo.h"

But then this caused the app to crash at runtime (in debug mode):

> 0x80131040 : The located assembly's manifest definition does not match the assembly reference.

Exception thrown at 0x00007FFF9F2B4B89 in CppWinRTToolkitIsland.exe: Microsoft C++ exception: winrt::hresult_error at memory location 0x00000052D38FAB78.
 	KernelBase.dll!RaiseException�()	Unknown
 	vcruntime140d_app.dll!00007fff4e9bb1f0()	Unknown
>	CppWinRTToolkitIsland.exe!winrt::throw_hresult(const winrt::hresult result) Line 4908	C++
 	CppWinRTToolkitIsland.exe!winrt::check_hresult(const winrt::hresult result) Line 4979	C++
 	CppWinRTToolkitIsland.exe!winrt::Windows::Foundation::IActivationFactory::ActivateInstance<winrt::CSharpIslandRuntimeComponent::ToolkitIsland>() Line 6414	C++
 	CppWinRTToolkitIsland.exe!winrt::CSharpIslandRuntimeComponent::ToolkitIsland::<lambda>(const winrt::Windows::Foundation::IActivationFactory & f) Line 37	C++
 	CppWinRTToolkitIsland.exe!winrt::CSharpIslandRuntimeComponent::ToolkitIsland <lambda>(const winrt::Windows::Foundation::IActivationFactory &)::<lambda_invoker_cdecl>(const winrt::Windows::Foundation::IActivationFactory & f) Line 37	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::factory_cache_entry<winrt::CSharpIslandRuntimeComponent::ToolkitIsland,winrt::Windows::Foundation::IActivationFactory>::call<winrt::CSharpIslandRuntimeComponent::ToolkitIsland (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &)>(winrt::CSharpIslandRuntimeComponent::ToolkitIsland(*)(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6246	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::call_factory_cast<winrt::CSharpIslandRuntimeComponent::ToolkitIsland (__cdecl*)(winrt::Windows::Foundation::IActivationFactory const &),winrt::CSharpIslandRuntimeComponent::ToolkitIsland,winrt::Windows::Foundation::IActivationFactory,winrt::CSharpIslandRuntimeComponent::ToolkitIsland <lambda>(const winrt::Windows::Foundation::IActivationFactory &)>(winrt::CSharpIslandRuntimeComponent::ToolkitIsland::winrt::CSharpIslandRuntimeComponent::ToolkitIsland <lambda>(const winrt::Windows::Foundation::IActivationFactory &) && callback) Line 6285	C++
 	CppWinRTToolkitIsland.exe!winrt::CSharpIslandRuntimeComponent::ToolkitIsland::ToolkitIsland() Line 39	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::ActivateType<winrt::CSharpIslandRuntimeComponent::ToolkitIsland>() Line 29	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::XamlUserType::ActivateInstance() Line 437	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::produce<winrt::CppWinRTToolkitIsland::implementation::XamlUserType,winrt::Windows::UI::Xaml::Markup::IXamlType>::ActivateInstance(void * * result) Line 863	C++
 	Windows.UI.Xaml.dll!DirectUI::ActivationAPI::ActivateInstance(const CClassInfo * pType, IInspectable * pOuter, IInspectable * * ppInstance) Line 42	C++
 	[Inline Frame] Windows.UI.Xaml.dll!DirectUI::ActivationAPI::ActivateInstance(const CClassInfo *) Line 29	C++
 	Windows.UI.Xaml.dll!DirectUI::XamlParserCallbacks::XamlManagedRuntimeRPInvokes_CreateInstance(XamlTypeToken tokType, XamlQualifiedObject * pqoInstance) Line 49	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CFxCallbacks::XamlManagedRuntimeRPInvokes_CreateInstance(XamlTypeToken) Line 1258	C++
 	Windows.UI.Xaml.dll!XamlManagedRuntime::CreateInstance(const XamlTypeToken & inXamlType, std::shared_ptr<XamlQualifiedObject> & returnQo) Line 40	C++
 	[Inline Frame] Windows.UI.Xaml.dll!XamlType::CreateInstance(std::shared_ptr<XamlQualifiedObject> &) Line 40	C++
 	Windows.UI.Xaml.dll!ObjectWriterRuntime::CreateTypeImpl(const XamlLineInfo & lineInfo, const std::shared_ptr<XamlType> & spType, const std::shared_ptr<ObjectWriterCallbacksDelegate> & spCallback, const std::shared_ptr<XamlQualifiedObject> & spRootObjectInstance, std::shared_ptr<XamlQualifiedObject> & spInstance) Line 76	C++
 	[Inline Frame] Windows.UI.Xaml.dll!ObjectWriterCommonRuntime::CreateType(const XamlLineInfo &) Line 116	C++
 	Windows.UI.Xaml.dll!BinaryFormatObjectWriter::CreateInstanceFromType(const ObjectWriterNode & node) Line 436	C++
 	Windows.UI.Xaml.dll!BinaryFormatObjectWriter::WriteNode(const ObjectWriterNode & inNode) Line 136	C++
 	Windows.UI.Xaml.dll!CParser::LoadXamlCore(CCoreServices * pCore, const CParserSettings & parserSettings, const Parser::XamlBuffer & buffer, CDependencyObject * * ppDependencyObject, const xstring_ptr_view & strSourceAssemblyName, const std::array<unsigned char,64> &) Line 284	C++
 	[Inline Frame] Windows.UI.Xaml.dll!CParser::LoadXaml(CCoreServices *) Line 46	C++
 	Windows.UI.Xaml.dll!CCoreServices::ParseXamlWithExistingFrameworkRoot(const Parser::XamlBuffer & buffer, CDependencyObject * pExistingFrameworkRoot, const xstring_ptr_view & strSourceAssemblyName, const xstring_ptr_view & strXamlResourceUri, const bool expandTemplatesDuringParse, CDependencyObject * * ppDependencyObject) Line 3687	C++
 	Windows.UI.Xaml.dll!CApplication::LoadComponent(CCoreServices * pCore, CDependencyObject * pComponent, IPALUri * pUri) Line 512	C++
 	Windows.UI.Xaml.dll!Application_LoadComponent(CCoreServices * pCore, CDependencyObject * pComponent, const xstring_ptr & strUri, ComponentResourceLocation::Enum resourceLocation) Line 385	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkApplication::LoadComponent(IInspectable * pComponent, const xstring_ptr & strUri, Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation resourceLocation) Line 553	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkApplicationFactory::LoadComponentWithResourceLocationImpl(IInspectable * pComponent, Windows::Foundation::IUriRuntimeClass * pUri, Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation resourceLocation) Line 500	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkApplicationFactory::LoadComponentWithResourceLocation(IInspectable * pComponent, Windows::Foundation::IUriRuntimeClass * pResourceLocator, Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation componentResourceLocation) Line 778	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::consume_Windows_UI_Xaml_IApplicationStatics<winrt::Windows::UI::Xaml::IApplicationStatics>::LoadComponent(const winrt::Windows::Foundation::IInspectable & component, const winrt::Windows::Foundation::Uri & resourceLocator, const winrt::Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation & componentResourceLocation) Line 265	C++
 	CppWinRTToolkitIsland.exe!winrt::Windows::UI::Xaml::Application::LoadComponent::__l2::<lambda>(const winrt::Windows::UI::Xaml::IApplicationStatics & f) Line 12248	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::call_factory<winrt::Windows::UI::Xaml::Application,winrt::Windows::UI::Xaml::IApplicationStatics,void <lambda>(const winrt::Windows::UI::Xaml::IApplicationStatics &)>(winrt::Windows::UI::Xaml::Application::LoadComponent::__l2::void <lambda>(const winrt::Windows::UI::Xaml::IApplicationStatics &) && callback) Line 6264	C++
 	CppWinRTToolkitIsland.exe!winrt::Windows::UI::Xaml::Application::LoadComponent(const winrt::Windows::Foundation::IInspectable & component, const winrt::Windows::Foundation::Uri & resourceLocator, const winrt::Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation & componentResourceLocation) Line 12249	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::MainPageT<winrt::CppWinRTToolkitIsland::implementation::MainPage>::InitializeComponent() Line 31	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::MainPage::MainPage() Line 12	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::heap_implements<winrt::CppWinRTToolkitIsland::implementation::MainPage>::heap_implements<winrt::CppWinRTToolkitIsland::implementation::MainPage>()	C++
 	CppWinRTToolkitIsland.exe!winrt::make<winrt::CppWinRTToolkitIsland::implementation::MainPage>() Line 7725	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::ActivateLocalType<winrt::CppWinRTToolkitIsland::implementation::MainPage>() Line 35	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::XamlUserType::ActivateInstance() Line 437	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::produce<winrt::CppWinRTToolkitIsland::implementation::XamlUserType,winrt::Windows::UI::Xaml::Markup::IXamlType>::ActivateInstance(void * * result) Line 863	C++
 	Windows.UI.Xaml.dll!DirectUI::ActivationAPI::ActivateInstance(const CClassInfo * pType, IInspectable * pOuter, IInspectable * * ppInstance) Line 42	C++
 	[Inline Frame] Windows.UI.Xaml.dll!DirectUI::ActivationAPI::ActivateInstance(const CClassInfo *) Line 29	C++
 	Windows.UI.Xaml.dll!DirectUI::NavigationCache::LoadContent(HSTRING__ * descriptor, IInspectable * * ppInstance) Line 148	C++
 	Windows.UI.Xaml.dll!DirectUI::NavigationCache::GetContent(DirectUI::PageStackEntry * pPageStackEntry, IInspectable * * ppIInspectable) Line 99	C++
 	Windows.UI.Xaml.dll!DirectUI::Frame::PerformNavigation() Line 512	C++
 	Windows.UI.Xaml.dll!DirectUI::Frame::StartNavigation() Line 434	C++
 	Windows.UI.Xaml.dll!DirectUI::Frame::NavigateImpl(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * pIInspectable, Windows::UI::Xaml::Media::Animation::INavigationTransitionInfo * navigationTransitionInfo, unsigned char * pCanNavigate) Line 382	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameGenerated::Navigate(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * pParameter, Windows::UI::Xaml::Media::Animation::INavigationTransitionInfo * pInfoOverride, unsigned char * pReturnValue) Line 494	C++
 	[Inline Frame] Windows.UI.Xaml.dll!DirectUI::Frame::NavigateImpl(Windows::UI::Xaml::Interop::TypeName) Line 340	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameGenerated::Navigate(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * pParameter, unsigned char * pReturnValue) Line 476	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::consume_Windows_UI_Xaml_Controls_IFrame<winrt::Windows::UI::Xaml::Controls::IFrame>::Navigate(const winrt::Windows::UI::Xaml::Interop::TypeName & sourcePageType, const winrt::Windows::Foundation::IInspectable & parameter) Line 6167	C++
 	CppWinRTToolkitIsland.exe!winrt::CppWinRTToolkitIsland::implementation::App::OnLaunched(const winrt::Windows::ApplicationModel::Activation::LaunchActivatedEventArgs & e) Line 74	C++
 	CppWinRTToolkitIsland.exe!winrt::impl::produce<winrt::CppWinRTToolkitIsland::implementation::App,winrt::Windows::UI::Xaml::IApplicationOverrides>::OnLaunched(void * args) Line 5047	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkApplicationGenerated::OnLaunchedProtected(Windows::ApplicationModel::Activation::ILaunchActivatedEventArgs * pArgs) Line 502	C++
 	Windows.UI.Xaml.dll!DirectUI::FrameworkView::OnActivated(Windows::ApplicationModel::Core::ICoreApplicationView * pSender, Windows::ApplicationModel::Activation::IActivatedEventArgs * pArgs) Line 267	C++
 	[Inline Frame] Windows.UI.Xaml.dll!Microsoft::WRL::Callback::__l2::<lambda_843e2d2bd208f22e7025354e109ff701>::operator()(Windows::UI::Core::ICoreWindow * &&) Line 335	C++
 	Windows.UI.Xaml.dll!Microsoft::WRL::Details::DelegateArgTraits<long (__cdecl Windows::Foundation::ITypedEventHandler_impl<Windows::Foundation::Internal::AggregateType<Windows::UI::Core::CoreWindow *,Windows::UI::Core::ICoreWindow *>,Windows::Foundation::Internal::AggregateType<Windows::UI::Core::WindowSizeChangedEventArgs *,Windows::UI::Core::IWindowSizeChangedEventArgs *>>::*)(Windows::UI::Core::ICoreWindow *,Windows::UI::Core::IWindowSizeChangedEventArgs *)>::DelegateInvokeHelper<Windows::Foundation::ITypedEventHandler<Windows::UI::Core::CoreWindow *,Windows::UI::Core::WindowSizeChangedEventArgs *>,<lambda_843e2d2bd208f22e7025354e109ff701>,-1,Windows::UI::Core::ICoreWindow *,Windows::UI::Core::IWindowSizeChangedEventArgs *>::Invoke(Windows::UI::Core::ICoreWindow * <args_0>, Windows::UI::Core::IWindowSizeChangedEventArgs * <args_1>) Line 245	C++
 	twinapi.appcore.dll!00007fff99220126()	Unknown
 	twinapi.appcore.dll!00007fff9920604d()	Unknown
 	rpcrt4.dll!00007fffa072a0e3()	Unknown
 	rpcrt4.dll!00007fffa07921cb()	Unknown
 	rpcrt4.dll!00007fffa06cb369()	Unknown
 	combase.dll!00007fffa0c59d3c()	Unknown
 	rpcrt4.dll!00007fffa070b71b()	Unknown
 	combase.dll!00007fffa0c21173()	Unknown
 	combase.dll!00007fffa0c20efe()	Unknown
 	combase.dll!00007fffa0c5e236()	Unknown
 	combase.dll!00007fffa0bfa283()	Unknown
 	combase.dll!00007fffa0c60f78()	Unknown
 	combase.dll!00007fffa0bc6aa6()	Unknown
 	combase.dll!00007fffa0c0bd54()	Unknown
 	combase.dll!00007fffa0c0bab2()	Unknown
 	combase.dll!00007fffa0c0b64d()	Unknown
 	combase.dll!00007fffa0c108d7()	Unknown
 	Windows.UI.dll!Windows::UI::Core::CDispatcher::ProcessMessage(bool bDrainQueue, bool * pbWindowMessagesProcessed, bool * pbInvokeItemProcessed) Line 332	C++
 	Windows.UI.dll!Windows::UI::Core::CDispatcher::WaitAndProcessMessagesInternal(bool bRunAlwaysOnce, void * hEventWait) Line 1950	C++
 	Windows.UI.dll!Windows::UI::Core::CDispatcher::WaitAndProcessMessages(void * hEventWait) Line 458	C++
 	twinapi.appcore.dll!00007fff991fe54a()	Unknown
 	SHCore.dll!00007fffa133e689()	Unknown
 	kernel32.dll!00007fffa05d7034()	Unknown
 	ntdll.dll!00007fffa15a2651()	Unknown

I submitted a PR to fix the doc XML here to enable the .NET Native tool chain, and then voila! I could run the app:

image

So it seems .NET Native is required for this to work? And you have to manually include the Xaml Type Info header currently?

Describe the bug

Steps to reproduce the bug

Steps to reproduce the behavior:

  1. Follow Guide: https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/use-csharp-component-from-cpp-winrt
  2. Add UserControl to C# Project
  3. Try and use new control in XAML by adding xmlns using statement and header to MainPage.h

Expected behavior
Control is usable in Debug or Release mode.

Actual behavior
Need to manually add the extra _XamlTypeInfo.h header and run with .NET Native enabled in Release mode.

Version Info
NuGet package version: Microsoft.Windows.CppWinRT.2.0.210505.3
No WinUI packages, Just File New Project from C++/WinRT VSIX Templates for Blank App for UWP.

Windows 10 version Saw the problem?
21H1 (19043) Yes
October 2020 Update (19042)
May 2020 Update (19041)
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop Yes
Xbox
Surface Hub
IoT

Additional context
Was trying to work on a Sample for CommunityToolkit/WindowsCommunityToolkit#3704 which was also called out here in Issue #4509.

@michael-hawker
Copy link
Collaborator Author

michael-hawker commented May 24, 2021

I've been putting a sample together for the Toolkit, so once I publish that I'll post a link here. This seems mostly like tooling and docs improvements for the future. I'll compare this to WinUI 3 in the future as well to see if the same pitfalls exist.

This article was useful as well in resolving references to other NuGet packages.

@asklar
Copy link
Member

asklar commented Jun 4, 2021

@michael-hawker the xamltypeinfo thing is sadly well known and storied. See:

Good catch on the .net native doc, glad to see it fixed.

michael-hawker added a commit to CommunityToolkit/Sample-Windows-CppWinRT that referenced this issue Jul 17, 2021
Ran into some issues see microsoft/microsoft-ui-xaml#5040
Had to manually add extra header and run in Release mode with .NET Native
TODO: Maybe we could run .NET Native in all release configurations to keep some debugging enabled for C++?
@kennykerr
Copy link

The Xaml compiler could make this problem go away by including the headers they depend on and not assuming the project will do it for them.

@asklar
Copy link
Member

asklar commented Aug 16, 2021

agreed but then we run into multiple files including the same set of big headers, so I think that's why XC expects you to add it to PCH instead

@kennykerr
Copy link

The Xaml compiler can include it regardless to avoid this pit of failure. Developers concerned about build performance are always able to add headers to the PCH (redundantly) to improve their build performance. The latter is a job an app developer is able and willing to do.

@bpulliam bpulliam removed the needs-triage Issue needs to be triaged by the area owners label Dec 6, 2022
@github-actions
Copy link

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Aug 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants