我要调用C语言函数:
f_api(void(*callback)(int))
我有一个回调的静态类方法:
struct A {
static void CallBack(int i) {
A::count = i;
}
static count = 0;
};
我可以这样调用函数:
f_api(&A::CallBack)
但是,我现在必须将回调更改为非静态,因为我必须创建多个A
对象。
但我不能改变f_api()
的定义。
我尝试使用lambda:
f_api([this](int i)->void{this->count = i;})`
但这失败了,因为我无法将带有捕获的lambda转换为简单的函数指针。
由于std::bind()
定义, f_api()
也无法完成工作。
我能为此做些什么?如何从lambda表达式中获取函数指针?有什么方法可以回避吗?
答案 0 :(得分:3)
如果您无法更改C API,那么我不认为您可以对此情况做很多事情。因为C函数需要将所需的所有信息作为函数参数传递。
您可以使用以下
将lambda转换为函数指针void (*ptr) () = []() {}
没有任何捕获的Lambda可以隐式转换为函数指针。但是捕获值的lambda无法转换为函数指针,因为它们具有额外的状态(以成员变量的形式)。
在C中解决此问题的常用方法是使用void*
参数。看一下pthread_create
函数。线程启动函数接受一个带有void*
参数的函数,该函数指向" context"。在您的情况下,此上下文可能类似于您调用方法的实例。
但是如果你不能改变C API,那么恐怕你对函数指针做不了多少。您唯一能做的就是使变量全局化,然后使用它们在函数指针中调用这些方法。
答案 1 :(得分:0)
以下是我的想法: 也许我不能通过从lambda获取函数指针来做到这一点。但是我做了一些其他的滴答来得到多个As来回避这个问题......
template<unsigned int ClassCount>
struct A {
static void CallBack(int i) {
A::count = i;
}
static int count;
};
template<unsigned int ClassCount>
int A<ClassCount>::count = 0;
所以我可以:
f_api(&A<0>::CallBack);
std::cout << A<0>::count << std::endl;
f_api(&A<1>::CallBack);
std::cout << A<1>::count << std::endl; // A<0>::count is different from A<1>::count
在某些情况下,这可能是一个潜在的解决方案,但遗憾的是,不是在矿井中。