C++ class member function callback

情到浓时终转凉″ 提交于 2019-11-27 14:33:29

This is impossible to do - in c++, you must use either a free function, or a static member function, or (in c++11) a lambda without capture to get a function pointer.

GCC allows you to create nested function which could do what you want, but only in C. It uses so-called trampolines to do that (basically small pieces of dynamically generated code). It would be possible to use this feature, but only if you split some of the code calling externalFunction to a separate C module.

Another possibility would be generating code at runtime eg. using libjit.

So if you're fine with non-reenrant function, create a global/static variable which will point to this and use it in your static function.

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

Its really horrible code, but I'm afraid you're out of luck with such a bad design as your externalFunction.

You can use Boost bind or TR1 bind (on recent compilers);;

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

Unfortunately, I lived in a pipe dream for the last 10 minutes. The only way forward is to call the target using some kind of a static wrapper function. The other answers have various neat (compiler-specific) tidbits on that, but here's the main trick:

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::function<>

Store a bound function in a variable like this:

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

(assuming C++0x support in compiler now. I'm sure Boost has a boost::function<> somewhere)

Vanilla C++ pointers-to-member-function

Without magic like that, you'd need pointer-to-memberfunction syntax:

See also live on http://ideone.com/Ld7It

Edit to clarify to the commenters, obviously this only works iff you have control over the definition of externalFunction. This is in direct response to the /broken/ snippet int the OP.

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 idiomatic solution

// 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;
}

Here is how I do this, when MyClass is a singleton:

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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!