Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在类内处理回调时,必须调用对非静态成员函数的引用_C++_C_C++11_Pointers_Callback - Fatal编程技术网

C++ 在类内处理回调时,必须调用对非静态成员函数的引用

C++ 在类内处理回调时,必须调用对非静态成员函数的引用,c++,c,c++11,pointers,callback,C++,C,C++11,Pointers,Callback,我有PiGPIO库提供的以下API代码。基本上,它允许您在pin状态更改时设置回调函数 通常API如下所示: typedef void (*gpio_callback_t)(int, int, uint32_t); int gpioSetAlertFunc(int, gpio_callback_t) void callback_func(int pin, int NewLevel, uint32_t CurrentTicks) { // Callback process } int

我有PiGPIO库提供的以下API代码。基本上,它允许您在pin状态更改时设置回调函数

通常API如下所示:

typedef void (*gpio_callback_t)(int, int, uint32_t);
int gpioSetAlertFunc(int, gpio_callback_t)
void callback_func(int pin, int NewLevel, uint32_t CurrentTicks)
{
    // Callback process
}

int main()
{
    // Setting up callback function
    gpioSetAlertFunc(10, callback_func)

    // Do stuff while callback will be called independently  
}
可以这样称呼:

typedef void (*gpio_callback_t)(int, int, uint32_t);
int gpioSetAlertFunc(int, gpio_callback_t)
void callback_func(int pin, int NewLevel, uint32_t CurrentTicks)
{
    // Callback process
}

int main()
{
    // Setting up callback function
    gpioSetAlertFunc(10, callback_func)

    // Do stuff while callback will be called independently  
}
现在,上面的代码可以完美地工作了


当我试图把这个代码包在C++类中时,问题就来了。 等级应如下所示:

class Pin
{
public:
    Pin()
    {
        gpioSetAlertFunc(10, this->internal_gpio_callback) );
    }

    void internal_callback_func(int pin, int level, uint32_t tick)
    {
        cout << "New level: " << pin << " " << level;
    }
}
类Pin码
{
公众:
Pin()
{
gpioSetAlertFunc(10,this->internal\u gpio\u回调);
}
无效内部回调函数(int pin、int level、uint32勾选)
{

cout一个未中断的C风格回调将接受一个
void*
参数来传递任意用户定义的数据。由于这个参数不接受,这是库设计中的一个错误。向库作者提出问题


为了解决这个问题,你需要创建一个C兼容函数的闭包。没有办法做到这一点,这是标准的C或C++。这就解决了这个问题。一个这样的库是,另一个是。这两个库都允许您创建类似于普通C函数的闭包。

gpio库代码没有您的
Pin
类的概念,但是您不能在不知道调用它的
Pin
对象的情况下调用您的成员回调函数。因此,您需要这样做查找要在函数调用中使用的
Pin
对象的me(非成员)函数

这些信息似乎是以
int pin
参数的形式出现的。因此,您需要一个(免费)函数,该函数了解所有
pin
对象及其管脚号,找到正确的管脚号并调用其回调函数:

class Pin
{
public:
    explicit Pin(int pin);
    void internal_callback_func(int level, uint32_t tick);
private:
    int _pin;
};

// Alternatively a std::array, a std::map or similar.
std::vector<Pin> allPins;

void pinCallback(int pin, int level, uint32_t tick)
{
    Pin& pinObject = allPins[pin];
    pinObject.internal_callback_func(level, tick);
    // The Pin object presumably knows its own number.
}

Pin::Pin(int pin) : _pin(pin)
{
    gpioSetAlertFunc(_pin, pinCallback);
}

void Pin::internal_callback_func(int level, uint32_t tick)
{
    cout << "New level: " << _pin << " " << level;
}

void mainOrSo()
{
    // Create some pins and store them in the vector. Each one registers the callback on construction.
    for (int i = 0; i < 16; ++i)
       allPins.emplace_back(i);
}
类Pin码
{
公众:
显式引脚(int引脚);
无效内部回调函数(整数级,uint32勾选);
私人:
int_引脚;
};
//或者使用std::数组、std::map或类似的方法。
std::向量allPins;
无效PincCallback(内部引脚、内部电平、uint32勾号)
{
引脚和引脚对象=所有引脚[引脚];
pinObject.internal_callback_func(级别,勾号);
//Pin对象可能知道自己的编号。
}
引脚::引脚(内部引脚):\u引脚(引脚)
{
gpioSetAlertFunc(_针,平扣式);
}
void Pin::内部回调函数(int级别,uint32勾选)
{

通常,回调提供一个客户机数据指针。使用客户机数据指针,您可以将回调方法设置为静态函数,并将对象指针作为客户机数据传递。因此,静态方法/回调函数可以使用对象指针/客户机数据访问对象成员。如果没有客户机数据,可能性非常小。唯一的可能性是,将对象指针存储在全局变量中,该变量可用于(静态)回调方法。回调函数的每个
int-pin
值是否恰好映射到一个
pin
对象?在问题中提供所有相关信息很重要。这个问题缺少一条基本信息,即
int-gpioSetalertFuncx的存在(未签名用户\u gpio、gpio\u回调\u t f、void*userdata)
。知道这条信息后,所有现有的答案和注释都变得无关紧要。@MaxLanghof我不确定这一点。@n.m.当时我不知道这条信息是否相关。但在这种情况下,为了让问题对其他人更具信息性,我想我们可以假设扩展函数api为not可用。好的,该库的问题是它还具有该函数的扩展版本,允许您传递一些用户数据。该函数是int-gpioSetAlertFuncEx(unsigned user\u gpio,gpio\u callback\u t f,void*userdata)。但我仍然看不到连接。这对我有什么帮助?@caffeine请问一个关于它的单独问题,或搜索此网站。有很多示例。必要时,您可以创建一个静态成员函数适配器,将其注册为回调,然后从那里调用非静态成员。将
void*
参数强制转换为
Pin*
。@咖啡因我知道的最好的方法是使用
重新解释cast
from/to
void*
/
Pin*