C2280 'winrt::hstring::hstring(std::nullptr_t)': attempting to reference a deleted function

324 views Asked by At

in cppcx, I have this piece of code:

auto frame = ref new Frame();
frame->Navigate(TypeName(CppCxInternalRefClass::typeid), ref new AnotherCppCxInternalRefClass(a, b, c,
                    ...));

which I am trying to convert to cppwinrt like this:

Frame frame;
frame.Navigate(
                utils::from_cx<winrt::TypeName>(TypeName(CppCxInternalRefClass::typeid)),
                utils::from_cx<winrt::Windows::UI::Xaml::FrameworkElement>(
                    ref new AnotherCppCxInternalRefClass(a, b, c,
                    ...)));

But I am getting an error:

Error C2280 'winrt::hstring::hstring(std::nullptr_t)': attempting to reference a deleted function

This is the function and line where I am getting the error:

template <typename T>
T from_cx(Platform::Object ^ from) {
===>T to{nullptr};
    winrt::guid iid = winrt::guid_of<T>();
    winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)->QueryInterface(
        reinterpret_cast<GUID&>(iid), reinterpret_cast<void**>(winrt::put_abi(to))));
    return to;

Looks like C++/CX we were able to get the typeid of a class by just doing ClassName:typeId which this code is doing. So there was a TypeName constructor which took it as an argument. But after changing to a struct in cppwinrt, it is expecting initializers for the two struct variables. I wasnt sure how to deal with this especially with ref classes in this code which my codebase is not ready to port to cppwinrt yet because of lack of support for idls at the moment. So I decided to just have the cppcx code but use the helper functions to convert them, but face this error while conversion.

But if I change the approach to something like this:

auto cppCxFrame = utils::to_cx<Frame>(frame);
            cppCxFrame->Navigate(TypeName(CppCxInternalRefClass::typeid),
                ref new AnotherCppCxInternalRefClass(a, b, c, ...));

it builds fine.

1

There are 1 answers

0
Ryan Shepherd On

If you can get a projection of the C++/CX classes via a winmd, then this is would be easy. Assuming you can't do that, you'll need to convert from a C++/CX TypeName to a C++/WinRT TypeName. The basic from_cx won't do that, because TypeName is a struct, not a runtimeclass, but it's straightforward to add overloads of from_cx to handle the TypeName struct, and the hstring it holds.

winrt::hstring from_cx(Platform::String^ const& from)
{
  winrt::hstring to;
  const HSTRING& fromHstring = reinterpret_cast<HSTRING>(from);
  winrt::copy_from_abi(to, fromHstring);
  return to;
}

winrt::Windows::UI::Xaml::Interop::TypeName from_cx(::Windows::UI::Interop::TypeName const& from)
{
  return {
    static_cast<winrt::Windows::UI::Xaml::Interop::TypeKind>(from.Kind),
    from_cx(from.Name)
  };
}