Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

co_await expression needs await_ready function

I have a Win32 programm, where I want to add some winRT calls. Among other things I want to open a file without a GUI interface.

I use the async file open call from the StorageFile class, because the next call needs an IStorageFile interface.

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

At the moment, the compiler complains that the co_await expression requires a suitable "await_ready" function and none was found.

I`m not sure if this is the case due to a missing header include or if "co_await" can not be used within a win32 application.

Edit: My visual studio project setup is: - use c++17, add cppwinrt.exe to my include directories, link against windowsapp.lib and use windows sdk version 10.0.17134.0.

like image 387
user5580578 Avatar asked Oct 16 '18 16:10

user5580578


1 Answers

The problem is that the openFile() function does not have the proper return type to handle co_await.

See the research and work that went into the answer I created for C++11 threads to update MFC application windows. SendMessage(), PostMessage() required? which contains a list of recommendations for various approaches to coroutines.

This question was about using C++/WinRT with MFC but the material also applies with WinAPI.

See as well synchronizing SDK with Windows 10 update and using WinRT with Standard C++ which contains a simple console application example using the Web Syndication async functionality to retrieve a list of URLs from an RSS feed. There are a number of links to documentation, some of which is a bit out dated now.

Addendum: Sample Console application

I created the following simple console application using Visual Studio 2017. I created the text file and then ran this in the debugger. I then renamed the text file and ran it again in the debugger and an exception was thrown since the file with that name no longer existed.

See also C++/WinRT, part of Windows SDK 17134 is not compatible with Visual Studio 15.8 Preview 3 which describes a compiler option you may need to change. I did.

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

I used the following properties settings.

Properties dialog screen shot showing General Properties

Properties dialog screen shot showing C/C++ All options

like image 139
Richard Chambers Avatar answered Nov 15 '22 13:11

Richard Chambers