繁体   English   中英

C ++类成员函数回调

[英]C++ class member function callback

我有以下问题。 我有一个来自外部库(无法修改)的函数,如下所示:

void externalFunction(int n, void udf(double*) );

我想将udf函数作为现有类的函数成员传递。 请看下面的代码:

// External function (tipically from an external library)
void externalFunction(int n, void udf(double*) )
{
     // do something
}

// User Defined Function (UDF)
void myUDF(double* a)
{
      // do something
}

// Class containing the User Defined Function (UDF)
class myClass
{
public:
    void classUDF(double* a)
    {
        // do something...
    };
};

int main()
{
    int     n=1;

    // The UDF to be supplied is myUDF
    externalFunction(n, myUDF);

    // The UDF is the classUDF member function of a myClass object
    myClass myClassObj;
    externalFunction(n, myClassObj.classUDF);   // ERROR!!
}

我不能将classUDF成员函数声明为静态函数,因此上面代码的最后一行导致编译错误!

这是不可能的 - 在c ++中,你必须使用自由函数或静态成员函数,或者(在c ++ 11中)没有捕获的lambda来获取函数指针。

GCC允许你创建嵌套的函数,它可以做你想要的,但只在C中。它使用所谓的trampolines来做到这一点(基本上是一小块动态生成的代码)。 可以使用此功能,但前提是您将一些调用externalFunction的代码拆分为单独的C模块。

另一种可能性是在运行时生成代码,例如。 使用libjit

因此,如果您对非重入函数没有问题,请创建一个全局/静态变量,该变量将指向this变量并在静态函数中使用它。

class myClass
{
public:
    static myClass* callback_this;
    static void classUDF(double* a)
    {
        callback_this.realUDF(a);
    };
};

它真的很可怕的代码,但我担心你的externalFunction这么糟糕的设计会让你失望。

您可以使用Boost绑定或TR1绑定(在最近的编译器上);;

 
 
 
 
  
  
  externalFunction(n, boost::bind(&myClass::classUDF, boost::ref(myClassObj)));
 
 
  

不幸的是,我在过去的10分钟里一直梦想着。 前进的唯一方法是使用某种静态包装函数调用目标。 其他答案有各种简洁(特定于编译器)的花絮,但这是主要技巧:

void externalFunction(int n, void (*udf)(double*) )
{ double x; udf(&x); }

myClass myClassObj;
void wrapper(double* d) { myClassObj.classUDF(d); }

int main()
{
    externalFunction(1, &wrapper);
}

的std ::功能<>

将绑定函数存储在变量中,如下所示:

std::function<void(double*)> stored = std::bind(&myClass::classUDF, boost::ref(myClassObj))

(假设编译器现在支持C ++ 0x。我确定Boost在某处有一个boost :: function <>)

Vanilla C ++指向成员函数的指针

没有这样的魔法,你需要指向成员函数的指针语法:

另见http://ideone.com/Ld7It

编辑澄清去提意见,显然这只能当且仅当你有超过externalFunction的定义控制。 这是对OP的/ broken / snippet int的直接响应。

struct myClass
{
    void classUDF(double* a) { };
};

void externalFunction(int n, void (myClass::*udf)(double*) )
{
    myClass myClassObj;
    double x;
    (myClassObj.*udf)(&x); 
}

int main()
{
    externalFunction(1, &myClass::classUDF);
}

C ++ 98惯用解决方案

// mem_fun_ref example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>

int main () 
{
    std::vector<std::string> numbers;

    // populate vector:
    numbers.push_back("one");
    numbers.push_back("two");
    numbers.push_back("three");
    numbers.push_back("four");
    numbers.push_back("five");

    std::vector <int> lengths (numbers.size());

    std::transform (numbers.begin(), numbers.end(), lengths.begin(), 
                std::mem_fun_ref(&std::string::length));

    for (int i=0; i<5; i++) {
        std::cout << numbers[i] << " has " << lengths[i] << " letters.\n";
    }
    return 0;
}

当MyClass是单身时,我就是这样做的:

void externalFunction(int n, void udf(double) );

class MyClass
{
public:
   static MyClass* m_this;
   MyClass(){ m_this = this; }
   static void mycallback(double* x){ m_this->myrealcallback(x); }
   void myrealcallback(double* x);
}

int main()
{
   MyClass myClass;
   externalFunction(0, MyClass::mycallback);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM