错误 C2664 'HRESULT IUnknown::QueryInterface(const IID &,void **)':无法将参数 1 从 'const winrt::guid' 转换为 'const IID &'

ssn*_*ssn 4 c++ windows-runtime c++-cx winrt-xaml c++-winrt

当我使用microsoft docs 中的帮助程序函数从 cx 迁移到 winrt时,会发生此错误。我在这里看到类似的问题,但提到的解决方案似乎不适合我。此处提到的解决方案在存在此错误的文件中的任何其他 winrt 标头之前添加 #include <Unknwn.h>。

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;
}
Run Code Online (Sandbox Code Playgroud)

这是整个文件:

#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)));
    }
}
}
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 6

winrt::guid_of()返回一个winrt::guid. 根据C++/WinRT 中的新增功能

  • 突破性的改变。GUID 现在被投影为winrt::guid. 对于您实现的 API,您必须使用winrt::guidGUID 参数。否则,只要在包含任何 C++/WinRT 标头之前包含 unknwn.hwinrt::guid,就会转换为 GUID 。请参阅与 ABI 的 GUID 结构互操作

根据与 ABI 的 GUID 结构的互操作

GUID被投影为winrt::guid. 对于您实现的 API,您必须使用winrt::guidforGUID参数。否则,只要在包含任何 C++/WinRT 标头之前包含(由 <windows.h> 和许多其他头文件隐式包含),winrt::guid就会在和之间进行自动转换。GUID unknwn.h

如果你不这样做,那么你就可以reinterpret_cast在他们之间进行硬拉。

因此,要么确保unknwn.h包含在 WinRT 标头之前,要么您可以reinterpret_cast显式地包含,例如:

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;
}
Run Code Online (Sandbox Code Playgroud)