Reputation: 2711
This error happens to me when I use the helper function from microsoft docs to migrate to winrt from cx. I see a similar question here, but the solution mentioned doesn't seem to work for me. The solution mentioned here add #include <Unknwn.h> before any other winrt headers in the file which has this error.
template <typename T>
T from_cx(Platform::Object ^ from) {
T to{nullptr};
winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)->QueryInterface(
winrt::guid_of<T>(), reinterpret_cast<void**>(winrt::put_abi(to))));
return to;
}
This is the entire file:
#pragma once
#include <Unknwn.h>
#include <winrt/Windows.Foundation.h>
namespace x {
namespace y {
template <typename T>
T from_cx(Platform::Object ^ from) {
T to{nullptr};
winrt::check_hresult(reinterpret_cast<::IUnknown*>(from)->QueryInterface(
winrt::guid_of<T>(), reinterpret_cast<void**>(winrt::put_abi(to))));
return to;
}
template <typename T>
T ^
to_cx(winrt::Windows::Foundation::IUnknown const& from) {
return safe_cast<T ^>(reinterpret_cast<Platform::Object ^>(winrt::get_abi(from)));
}
}
}
Upvotes: 4
Views: 1048
Reputation: 2711
IInspectable's comment also worked for me:
If you #include <Unknwn.h>, make sure you really include it prior to any winrt headers. When using precompiled headers, that's where you have to include Unknwn.h as well.
.....It's vital that your compilation units have the Unknwn.h included before any other winrt header files. Compilation units commonly have a file extension of .cpp, .cc, or .cxx.
I thought the header had to be included in the file defining those helper functions.
Upvotes: 0
Reputation: 595319
winrt::guid_of()
returns a winrt::guid
. Per What's new in C++/WinRT:
- Breaking change. GUID is now projected as
winrt::guid
. For APIs that you implement, you must usewinrt::guid
for GUID parameters. Otherwise,winrt::guid
converts to GUID, as long as you include unknwn.h before you include any C++/WinRT headers. See Interoperating with the ABI's GUID struct.
Per Interoperating with the ABI's GUID struct:
GUID
is projected aswinrt::guid
. For APIs that you implement, you must usewinrt::guid
forGUID
parameters. Otherwise, there are automatic conversions betweenwinrt::guid
andGUID
as long as you includeunknwn.h
(implicitly included by <windows.h> and many other header files) before you include any C++/WinRT headers.If you don't do that, then you can hard-
reinterpret_cast
between them.
So, either make sure unknwn.h
is included before WinRT headers, or else you can reinterpret_cast
explicitly, eg:
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;
}
Upvotes: 6