如何将函数调用与回调同步?
How to Synchronize function calls with callbacks?
我正在使用一个 SDK,它提供了一些功能和一个回调来发送结果。代码在 C++ 中。
SDK APIs:
typedef void(*onSdkCallBackFn)(int cmdType, const char *jsonResult);
void SetCallback(onSdkIotCallBackFn Fn);
void SetCommand(int commandId);
SetCommand没有return值,需要等待SDK通过回调发送结果。
我需要为上层提供自己的API,但他们希望通过函数调用得到结果,而不打算通过回调接收。
这是我的示例代码:
void MyCallback(int cmdType, const char *jsonResult)
{
int result;
if (cmfType == 5)
result = 100;
else
result = 0;
}
int DoCommandNo5()
{
int result = -1; // need to be updated in callback function
etCallback(&MyCallback);
DoCommand(5);
// here I need to wait for result through SDK callback and return it.
// How to handle it?
return result;
}
我可以不使用线程来做到这一点吗?处理此任务的最佳方法是什么?
我检查了这些方法:WaitForSingleObject 和 std::condition_variable 但似乎两者都需要创建单独的线程。
感谢任何建议和帮助。
由于细节不明确,我将从非常笼统的角度回答如何将基于事件驱动的功能包装到标准函数中。
我希望结果可以全局访问或以某种方式传递给回调函数。因此,在期望回调设置实际结果的函数中,可以只做 waiting while 循环。例如:
int result;
void TheCallback() {
...
result = 255;
...
}
int TheCallbackWrapper() {
...
result = -1; // let's assume -1 means result is not yet set
while (result == -1) {
sleep(1); // an assumption of system call to sleep the execution for 1 ms, just not to eat CPU time too much
}
return result; // if we reach this point, then the callback has set a result ready to be returned
}
好吧,一种方法是,例如等待 std::condition_variable
:
int DoCommandNo5()
{
int result = -1;
bool resultReady = false;
std::mutex m;
std::unique_lock<std::mutex> lk(m);
std::condition_variable cv;
auto getResult = [&](int commandResult) {
resultReady = true;
result = commandResult;
cv.notify_one();
};
setCallback(getResult);
doCommand(5);
cv.wait(lk, [&]{return resultReady;});
return result;
}
您还可以调用 cv.wait_for
方法,这样 DoCommandNo5
函数就不会无限阻塞。
我正在使用一个 SDK,它提供了一些功能和一个回调来发送结果。代码在 C++ 中。
SDK APIs:
typedef void(*onSdkCallBackFn)(int cmdType, const char *jsonResult);
void SetCallback(onSdkIotCallBackFn Fn);
void SetCommand(int commandId);
SetCommand没有return值,需要等待SDK通过回调发送结果。
我需要为上层提供自己的API,但他们希望通过函数调用得到结果,而不打算通过回调接收。 这是我的示例代码:
void MyCallback(int cmdType, const char *jsonResult)
{
int result;
if (cmfType == 5)
result = 100;
else
result = 0;
}
int DoCommandNo5()
{
int result = -1; // need to be updated in callback function
etCallback(&MyCallback);
DoCommand(5);
// here I need to wait for result through SDK callback and return it.
// How to handle it?
return result;
}
我可以不使用线程来做到这一点吗?处理此任务的最佳方法是什么?
我检查了这些方法:WaitForSingleObject 和 std::condition_variable 但似乎两者都需要创建单独的线程。
感谢任何建议和帮助。
由于细节不明确,我将从非常笼统的角度回答如何将基于事件驱动的功能包装到标准函数中。
我希望结果可以全局访问或以某种方式传递给回调函数。因此,在期望回调设置实际结果的函数中,可以只做 waiting while 循环。例如:
int result;
void TheCallback() {
...
result = 255;
...
}
int TheCallbackWrapper() {
...
result = -1; // let's assume -1 means result is not yet set
while (result == -1) {
sleep(1); // an assumption of system call to sleep the execution for 1 ms, just not to eat CPU time too much
}
return result; // if we reach this point, then the callback has set a result ready to be returned
}
好吧,一种方法是,例如等待 std::condition_variable
:
int DoCommandNo5()
{
int result = -1;
bool resultReady = false;
std::mutex m;
std::unique_lock<std::mutex> lk(m);
std::condition_variable cv;
auto getResult = [&](int commandResult) {
resultReady = true;
result = commandResult;
cv.notify_one();
};
setCallback(getResult);
doCommand(5);
cv.wait(lk, [&]{return resultReady;});
return result;
}
您还可以调用 cv.wait_for
方法,这样 DoCommandNo5
函数就不会无限阻塞。