Repository navigation
Bug: Cannot winrt::box_value a wchar_t #1566
Description
Activity
Char is char16_t, not wchar_t. So, you can't box a wchar_t, but you should be able to box a char16_t.
Nope. The code generated by cppwinrt from the idl was using wchar_t from what I see in the build error.
And the winrt::impl::reference_traits template does not have a specialization for either wchar_t or char16_t
winrt::impl::reference_traits does have a char16_t specialization.
cppwinrt/strings/base_reference_produce.h
Lines 180 to 185 in f23b41e
| template <> | |
| struct reference_traits<char16_t> | |
| { | |
| static auto make(char16_t value) { return Windows::Foundation::PropertyValue::CreateChar16(value); } | |
| using itf = Windows::Foundation::IReference<char16_t>; | |
| }; |
As for the error message, winrt::impl::category also has a specialization for char16_t.
cppwinrt/strings/base_identity.h
Line 594 in f23b41e
| template <> struct category<char16_t> { using type = basic_category; }; |
It has been this way for 7 years, so it isn't anything new.
My bad. I can winrt::box_value a char16_t. But using Char in idl gives me this error:
2> 3>C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\impl\Windows.Foundation.1.h(145,29): error C2338: static assertion failed: 'T must be WinRT type.'
2> (compiling source file '/Generated%20Files/XamlTypeInfo.g.cpp')
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\impl\Windows.Foundation.1.h(145,29):
2> the template instantiation context (the oldest one first) is
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\XamlTypeInfo.g.cpp(224,1):
2> see reference to function template instantiation 'winrt::Windows::Foundation::IInspectable winrt::UWPMain::implementation::GetValueTypeMember_MyProperty<winrt::UWPMain::MainPage,wchar_t>(const winrt::Windows::Foundation::IInspectable &)' being compiled
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\XamlTypeInfo.g.cpp(71,21):
2> see reference to function template instantiation 'winrt::Windows::Foundation::IInspectable winrt::box_value<wchar_t,0>(const T &)' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\Windows.Foundation.h(3093,47):
2> see reference to class template instantiation 'winrt::impl::reference_traits<wchar_t>' being compiled
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\Windows.Foundation.h(2680,21):
2> while compiling class template member function 'auto winrt::impl::reference_traits<wchar_t>::make(const T &)'
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\Windows.Foundation.h(3093,47):
2> see the first reference to 'winrt::impl::reference_traits<wchar_t>::make' in 'winrt::box_value'
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\XamlTypeInfo.g.cpp(71,21):
2> see the first reference to 'winrt::box_value' in 'winrt::UWPMain::implementation::GetValueTypeMember_MyProperty'
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\Windows.Foundation.h(2680,58):
2> see reference to function template instantiation 'auto winrt::make<winrt::impl::reference<T>,const T&>(const T &)' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(7870,28):
2> see reference to variable template 'const bool is_destructible_v<winrt::impl::reference<wchar_t> >' being compiled
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(7870,28):
2> see reference to class template instantiation 'winrt::impl::reference<T>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\Windows.Foundation.h(2572,24):
2> see reference to class template instantiation 'winrt::implements<winrt::impl::reference<T>,winrt::Windows::Foundation::IReference<T>,winrt::Windows::Foundation::IPropertyValue>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(7930,31):
2> see reference to alias template instantiation 'winrt::impl::producers<D,winrt::Windows::Foundation::IReference<T>,winrt::Windows::Foundation::IPropertyValue>' being compiled
2> with
2> [
2> D=winrt::impl::reference<wchar_t>,
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(6638,41):
2> see reference to alias template instantiation 'winrt::impl::tuple_if<winrt::impl::is_interface,std::tuple<winrt::Windows::Foundation::IReference<T>,winrt::Windows::Foundation::IPropertyValue>>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(6555,60):
2> see reference to class template instantiation 'winrt::impl::tuple_if_base<winrt::impl::is_interface,std::tuple<winrt::Windows::Foundation::IReference<T>,winrt::Windows::Foundation::IPropertyValue>>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(6552,122):
2> see reference to class template instantiation 'winrt::impl::is_interface<winrt::Windows::Foundation::IReference<T>>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\base.h(6558,32):
2> see reference to class template instantiation 'std::disjunction<std::is_base_of<winrt::Windows::Foundation::IInspectable,T>,winrt::impl::is_classic_com_interface<T>>' being compiled
2> with
2> [
2> T=winrt::Windows::Foundation::IReference<wchar_t>
2> ]
2> C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\MSVC\14.50.35717\include\xtr1common(162,79):
2> see reference to class template instantiation 'winrt::Windows::Foundation::IReference<T>' being compiled
2> with
2> [
2> T=wchar_t
2> ]
2>
2>Build FAILED.
2>
2> "C:\Users\Peter\Desktop\UWPWithWin32\Package\Package.wapproj" (build target) (1) ->
2> "C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\UWPMain.vcxproj" (default target) (3:7) ->
2> (CompileXamlGeneratedFiles target) ->
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\UWPMain.h(32,67): warning C4244: 'argument': conversion from 'int32_t' to 'T', possible loss of data
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\UWPMain.h(32,67): warning C4244: with
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\UWPMain.h(32,67): warning C4244: [
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\UWPMain.h(32,67): warning C4244: T=char16_t
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\UWPMain.h(32,67): warning C4244: ]
2>
2>
2> "C:\Users\Peter\Desktop\UWPWithWin32\Package\Package.wapproj" (build target) (1) ->
2> "C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\UWPMain.vcxproj" (default target) (3:7) ->
2> (CompileXamlGeneratedFiles target) ->
2> C:\Users\Peter\Desktop\UWPWithWin32\UWPMain\Generated Files\winrt\impl\Windows.Foundation.1.h(145,29): error C2338: static assertion failed: 'T must be WinRT type.'
It's the same for winui3. Should I file this issue to winui's repo instead?
It definitely is a bug for the WinUI team, but I do consider C++/WinRT's use of char16_t instead of wchar_t for Char a bug as well.
It is a bit surprising that winrt::hstring uses wchar_t for its character type, but the actual character type is char16_t.
It is a confusing thing:
At the ABI level, the HSTRING underlying data for WinRT is char16_t (unsigned 16 bit integer).
At the C++/WinRT level, the public interface of winrt:: hstring uses wchar_t.
hstring probably uses wchar_t for convenience because of the large amount of legacy APIs that take and hand wchar_t strings.
In this case the bug is on WinUI for interpreting Char in metadata as wchar_t, it looks like this wasn't even tested.
From the perspective of C++'s future evolution, char16_t should be used instead of wchar_t, because the width of wchar_t is configurable, making it unsuitable for cross-platform UTF-16 representation. As a result, future C++ Unicode facilities will only provide APIs using char16_t. I believe changing hstring's value_type to char16_t is a potential improvement for C++/WinRT 4.0, while still allowing construction of hstring from wchar_t to support legacy code.
Version
No response
Summary
From this documentation, it should be able to expose a
Chartype from the idl, but doing this will cause a compile error:Reproducible example
Use this idl
[default_interface] runtimeclass MainPage : Windows.UI.Xaml.Controls.Page { MainPage(); Char MyProperty; }Expected behavior
Compiles
Actual behavior
No response
Additional comments
No response