【问题标题】:Error C2664 'HRESULT IUnknown::QueryInterface(const IID &,void **)': cannot convert argument 1 from 'const winrt::guid' to 'const IID &'错误 C2664 'HRESULT IUnknown::QueryInterface(const IID &,void **)': 无法将参数 1 从 'const winrt::guid' 转换为 'const IID &'
【发布时间】:2020-12-02 13:50:40
【问题描述】:

当我使用来自microsoft docs to migrate to winrt from cx 的帮助函数时,我发生了这个错误。我看到一个类似的问题here,但提到的解决方案似乎对我不起作用。此处提到的解决方案在有此错误的文件中的任何其他 winrt 标头之前添加#include

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

这是整个文件:

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

【问题讨论】:

  • 如果您是 #include &lt;Unknwn.h&gt;,请确保您确实在任何 winrt 标头之前包含它。使用预编译头文件时,您还必须在其中包含 Unknwn.h
  • 您好,我在上面添加了文件的全部内容进行了编辑。我确实在任何其他标题之前都有包含。
  • 您发布了一个头文件。头文件不是编译单元。您的编译单元 必须在任何其他winrt 头文件之前包含Unknwn.h。编译单元的文件扩展名通常为 .cpp、.cc 或 .cxx。

标签: c++ windows-runtime winrt-xaml c++-cx c++-winrt


【解决方案1】:

winrt::guid_of() 返回一个winrt::guid。每What's new in C++/WinRT:

  • 重大变化。 GUID 现在投影为winrt::guid。对于您实现的 API,您必须将 winrt::guid 用于 GUID 参数。否则,winrt::guid 将转换为 GUID,只要在包含任何 C++/WinRT 标头之前包含 unknwn.h。见Interoperating with the ABI's GUID struct

Interoperating with the ABI's GUID struct

GUID 投影为 winrt::guid。对于您实现的 API,您必须将 winrt::guid 用于 GUID 参数。否则,winrt::guidGUID 之间存在自动转换只要在包含任何 C++/WinRT 头文件之前包含 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;
}

【讨论】:

  • @ssn 我更新了我的示例。如果仍然错误,则显示实际错误
【解决方案2】:

IInspectable 的评论也对我有用:

如果您#include ,请确保您确实包含它之前 任何 winrt 标头。当使用预编译的头文件时,这就是你 还必须包括 Unknwn.h。

.....你的编译单元必须包含 Unknwn.h 在任何其他 winrt 头文件之前。编译单元通常有一个 .cpp、.cc 或 .cxx 的文件扩展名。

我认为头文件必须包含在定义这些辅助函数的文件中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2021-02-14
    • 1970-01-01
    相关资源
    最近更新 更多