我有第三方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
成员的情况下实现这一目标;因为每次第三方lib调用回调时我都需要关联/使用状态。
谢谢!
答案 0 :(得分:0)
您将不得不以某种方式将非成员与函数指针相关联,因为它不会采用任何类型的上下文参数。你将在某个时刻拥有一个非成员函数,没有办法解决这个问题。而且这个功能不能成为捕获lambda。
一个选项是拥有一个(可能是线程本地的)全局指针来保存实例。
即。你这样做:
if(parent){
parent.removeChild(this);
}
另一个选择是使用libffi的闭包系统在运行时创建一个函数,并让实例成为已保存数据的一部分。我经常使用这种模式,但这里粘贴起来有点复杂。
答案 1 :(得分:0)
有没有办法在不使用静态成员的情况下实现这一点;
有一种解决方案。
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;