将接受回调的函数调用转换为协程
Turning a function call which takes a callback into a coroutine
我正在探索并尝试学习 C++ 协程(在 C++20 中添加)。我正在使用的一个 SDK 具有异步 API 调用,它们都接受回调,回调是在 SDK 管理的某些后台线程上调用的。
namespace third_party {
bool api_call(const std::string& some_parameter, const std::function<void(std::error_code)>& callback);
} // namespace third_party
我想将此 API 调用包装到可以等待的内容中:
namespace my_third_party_sdk_wrapper {
cppcoro::task<std::error_code> api_call(const std::string& some_parameter);
cppcoro::task<std::error_code> api_call(const std::string& some_parameter, cppcoro::cancellation_token token);
} // namespace my_third_party_sdk_wrapper
我正在考虑使用 cppcoro 库,但这不是必需的,除非这样做使包装器的实现变得更加简单。
问题是我不知道如何实现包装器。
陈峰的文章写得真好,你可以找找here。
对于你的情况,你可以这样做。
namespace my_third_party_async_sdk_wrapper
{
auto api_call_async(const std::string& some_parameter)
{
struct awaiter : public std::experimental::suspend_always
{
awaiter(const std::string ¶meter)
:parameter_(parmeter) {}
bool await_ready() { return false; }
void await_suspend(std::experimental::coroutine_handle<> handle)
{
// use your third party lib call directly here.
api_call(parameter_, [handle]()
{
// call the handle to resume the coroutine
handle();
}
}
const std::string parameter_;
};
return awaiter(some_parameter);
}
}
这应该可以满足您的要求。
关于 cppreference.com、“switch_to_new_thread”的简单 (运行) 示例:https://en.cppreference.com/w/cpp/language/coroutines
打开有两个问题:
- 向回调传递参数
- 将回调链接到调用堆栈
此代码显示了一个解决方案 https://wandbox.org/permlink/OGjmtFWsgjnn3GxX
在此处查找最新版本:https://github.com/andreaspfaffenbichler/Continuation/blob/master/Continuation.cpp
我正在探索并尝试学习 C++ 协程(在 C++20 中添加)。我正在使用的一个 SDK 具有异步 API 调用,它们都接受回调,回调是在 SDK 管理的某些后台线程上调用的。
namespace third_party {
bool api_call(const std::string& some_parameter, const std::function<void(std::error_code)>& callback);
} // namespace third_party
我想将此 API 调用包装到可以等待的内容中:
namespace my_third_party_sdk_wrapper {
cppcoro::task<std::error_code> api_call(const std::string& some_parameter);
cppcoro::task<std::error_code> api_call(const std::string& some_parameter, cppcoro::cancellation_token token);
} // namespace my_third_party_sdk_wrapper
我正在考虑使用 cppcoro 库,但这不是必需的,除非这样做使包装器的实现变得更加简单。
问题是我不知道如何实现包装器。
陈峰的文章写得真好,你可以找找here。
对于你的情况,你可以这样做。
namespace my_third_party_async_sdk_wrapper
{
auto api_call_async(const std::string& some_parameter)
{
struct awaiter : public std::experimental::suspend_always
{
awaiter(const std::string ¶meter)
:parameter_(parmeter) {}
bool await_ready() { return false; }
void await_suspend(std::experimental::coroutine_handle<> handle)
{
// use your third party lib call directly here.
api_call(parameter_, [handle]()
{
// call the handle to resume the coroutine
handle();
}
}
const std::string parameter_;
};
return awaiter(some_parameter);
}
}
这应该可以满足您的要求。
关于 cppreference.com、“switch_to_new_thread”的简单 (运行) 示例:https://en.cppreference.com/w/cpp/language/coroutines
打开有两个问题:
- 向回调传递参数
- 将回调链接到调用堆栈
此代码显示了一个解决方案 https://wandbox.org/permlink/OGjmtFWsgjnn3GxX
在此处查找最新版本:https://github.com/andreaspfaffenbichler/Continuation/blob/master/Continuation.cpp