[英]Converting a lambda to function pointer typedef
我有一個第三方API,該API具有將函數指針作為參數(示例類型)的函數:
// defined in "Api.h"
typedef int (*Callback) (int x);
unsigned char ApiCall(int p, Callback cb);
int ApiCall(int p, Callback cb) {
return cb(p);
}
我正在嘗試使用類實例方法與此API進行交互; 這是一個示例類:
class ApiWrapper {
public:
int ApiCallback(int x) { return this->factor_ * x; }
static int WorkingApiCallback(int x) { return 3 * x; }
ApiWrapper(int f) { this->factor_ = f; }
private:
int factor_;
}
並測試一個主要功能:
#include <iostream>
#include <functional>
int main() {
ApiWrapper a(2);
using std::placeholders::_1;
std::function<int(int)> lambda = std::bind( &ApiWrapper::ApiCallback, a, _1 );
std::cout << "Class: " << a.ApiCallback(21) << std::endl;
std::cout << "Lambda: " << lambda(21) << std::endl;
std::cout << "Static ApiCall:" << ApiCall(21, ApiWrapper::WorkingApiCallback) << std::endl;
// NOT WORKING
std::cout << "Static ApiCall:" << ApiCall(21, lambda) << std::endl;
std::cout << "Static ApiCall:" << ApiCall(21, this.ApiCallback) << std::endl;
return 0;
}
有沒有一種方法可以不使用static
成員來實現? 因為每次第三方庫調用回調時,我都需要關聯/使用狀態。
謝謝!
您將必須以某種方式將非成員與函數指針相關聯,因為它不需要任何類型的上下文參數。 您將在某個時候擁有一個非成員函數,沒有辦法解決。 而且該函數不能是捕獲的lambda。
一種選擇是擁有一個(可能是線程局部的)全局指針來保存實例。
即你做:
myType * glbInst;
..void someFunc()
{
myType myInst;
glbInst = &myInst;
apiCall([] (int) glbInst->member(x); });
}
另一種選擇是使用libffi的閉包系統在運行時創建一個函數,並將實例作為已保存數據的一部分。 我經常使用此模式,但在此處粘貼有點復雜。
有沒有一種方法可以不使用靜態成員來實現?
有一個棘手的解決方案。
ApiWrapper* objectForCallback = NULL;
int NonMemberFunction(int x)
{
assert(objectForCallback != NULL);
return objectForCallback->ApiCallback(x);
}
以及上面的設置可以正常工作:
ApiWrapper a(2);
objectForCallback = &a;
現在您可以使用:
std::cout << "Static ApiCall:" << ApiCall(21, NonMemberFunction) << std::endl;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.