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)));
}
}
}
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;
}