我使用的SDK提供了一些函数和一个回调来发送结果。代码是用C++编写的。
SDK API:
typedef void(*onSdkCallBackFn)(int cmdType, const char *jsonResult);
void SetCallback(onSdkIotCallBackFn Fn);
void SetCommand(int commandId);
SetCommand没有返回值,因此需要等待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,但似乎两者都需要创建单独的线程。
任何建议和帮助都将不胜感激。
一种方法是等待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
函数就不会无限阻塞。
由于细节很模糊,我将从一个非常一般的角度来回答如何将基于事件驱动的功能包装成标准函数。
我希望结果可以全局访问,或者以某种方式传递给回调函数。因此,在期望回调设置实际结果的函数中,可以只执行等待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
}