co_await expression needs await_ready function
Asked Answered
B

1

6

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.

Barcellona answered 16/10, 2018 at 16:39 Comment(0)
L
6

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

Lifesaving answered 16/10, 2018 at 17:30 Comment(5)
Very cool. One further question: how is it possible to wait in the main thread as long as the concurrency tasks is running?Barcellona
@Barcellona My understanding is that under the hood there are gnarly bits that do the actual thread management along with the join that is the main thread waiting for the coroutine to complete. The nice thing about coroutines is that they hide the mechanics nicely and are easy to use.Lifesaving
@Barcellona I have updated my answer with a short sample Windows console application using WinRT with co_await. I think I have provided all the pertinent details.Lifesaving
Thank you very much for your help! Everything is working as expected.Barcellona
More useful information can be found here: (learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/…)Barcellona

© 2022 - 2024 — McMap. All rights reserved.