将 lambda 转换为函数指针类型定义

Converting a lambda to function pointer typedef

本文关键字:指针 类型 定义 函数 lambda 转换      更新时间:2023-10-16

我有一个第三方 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 成员的情况下实现这一点;因为每次第三方库调用回调时,我都需要关联/使用状态。

  • 在线可运行来源:https://ideone.com/7nVSi8

谢谢!

您将不得不以某种方式将非成员与函数指针相关联,因为它不需要任何类型的上下文参数。您将在某个时候拥有一个非成员函数,无法解决这个问题。并且该函数不能是捕获 lambda。

一种选择是使用一个(可能是线程本地(全局指针来保存实例。

即您:

myType * glbInst;
..void someFunc()
{
 myType myInst;
  glbInst = &myInst;
  apiCall([] (int)  glbInst->member(x); });
}

另一种选择是使用 libffi 的闭包系统在运行时创建一个函数,并使实例成为保存数据的一部分。我经常使用这种模式,但粘贴在这里有点复杂。

有没有办法在不使用静态成员的情况下实现这一点;

有一个黑客解决方案。

  1. 定义非成员函数。
  2. 存储指向可由非成员函数访问的对象的指针。
  3. 从非成员函数调用对象的成员函数。

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;    
相关文章: