【问题标题】:co_await expression needs await_ready functionco_await 表达式需要 await_ready 函数
【发布时间】:2018-10-16 16:39:12
【问题描述】:

我有一个 Win32 程序,我想在其中添加一些 winRT 调用。我想在没有 GUI 界面的情况下打开文件。

我使用 StorageFile 类中的异步文件打开调用,因为下一个调用需要 IStorageFile 接口。

#include <roapi.h>
#include <winrt/Windows.Storage.h> 
#include <winrt/Windows.Foundation.h>

void openFile()
{
   using namespace winrt;
   using namespace winrt::Windows::Foundation;
   using namespace winrt::Windows::Storage;

   HRESULT rtn = RoInitialize(RO_INIT_MULTITHREADED); 
   winrt::hstring path{ L"C:\\Users...\\mytextfile.txt"};

   //wait for open the file 
   auto file = co_await StorageFile::GetFileFromPathAsync(path);

   //IStorageFile interface needed  
}

int main()
{
  openFile(); 
  return 0;
}

目前,编译器抱怨 co_await 表达式需要一个合适的“await_ready”函数,但没有找到。

我不确定这是否是由于缺少标头包含,或者“co_await”是否无法在 win32 应用程序中使用。

编辑: 我的视觉工作室项目设置是: - 使用 c++17,将 cppwinrt.exe 添加到我的包含目录,链接到 windowsapp.lib 并使用 windows sdk 版本 10.0.17134.0。

【问题讨论】:

    标签: c++ winapi c++-winrt


    【解决方案1】:

    问题在于openFile() 函数没有正确的返回类型来处理co_await

    查看我为 C++11 threads to update MFC application windows. SendMessage(), PostMessage() required? 创建的答案中的研究和工作,其中包含对各种协程方法的建议列表。

    这个问题是关于将 C++/WinRT 与 MFC 结合使用,但该材料也适用于 WinAPI。

    另请参阅synchronizing SDK with Windows 10 update and using WinRT with Standard C++,其中包含一个简单的控制台应用程序示例,该示例使用 Web Syndication 异步功能从 RSS 提要中检索 URL 列表。有许多文档链接,其中一些现在有点过时了。

    附录:控制台应用程序示例

    我使用 Visual Studio 2017 创建了以下简单的控制台应用程序。我创建了文本文件,然后在调试器中运行它。然后我重命名了文本文件并在调试器中再次运行它并引发了异常,因为具有该名称的文件不再存在。

    另请参阅C++/WinRT, part of Windows SDK 17134 is not compatible with Visual Studio 15.8 Preview 3,其中描述了您可能需要更改的编译器选项。我做到了。

    // console_winrt.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    // Requires the following changes to the project properties in the C++ compiler section.
    //   - C++ language standard must be set to C++17
    //   - Add /await to the Additional options
    
    #include "pch.h"
    
    #pragma comment(lib, "windowsapp")
    
    #include <winrt/Windows.Storage.h> 
    #include <winrt/Windows.Foundation.h>
    
    #include <iostream>
    
    winrt::Windows::Foundation::IAsyncAction  openMyFile()
    {
    
        winrt::hstring path{ L"D:\\Users\\rickc\\mytextfile.txt" };
    
        //wait for open the file 
        auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(path);
    
        //IStorageFile interface needed 
        auto xDate = file.DateCreated();
        std::cout << "file was found " << std::endl;
    }
    
    int main()
    {
        // initialize the WinRT apartment.
        winrt::init_apartment();
    
        auto x = openMyFile();
    
        // wait on the file access since that is all we are doing and we need to give it time.
        x.get();
        return 0;
    }
    

    我使用了以下属性设置。

    【讨论】:

    • 非常酷。还有一个问题:只要并发任务正在运行,怎么可能在主线程中等待?
    • @user5580578 我的理解是,在引擎盖下有一些粗糙的位来执行实际的线程管理以及等待协程完成的主线程的连接。协程的好处在于它们很好地隐藏了机制并且易于使用。
    • @user5580578 我已经使用带有co_await 的 WinRT 的简短示例 Windows 控制台应用程序更新了我的答案。我想我已经提供了所有相关的细节。
    • 非常感谢您的帮助!一切都按预期工作。
    • 更多有用的信息可以在这里找到:(docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/…)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 2011-07-08
    相关资源
    最近更新 更多