C++类成员函数回调

2022-01-03 00:00:00 function class callback c++ member

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

I have the following problem. I have a function from an external library (which cannot be modified) like this:

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

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

I would like to pass as the udf function above a function member of an existing class. Please look at the following code:

// 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 成员函数声明为静态函数,因此上面代码的最后一行导致编译错误!

I cannot declare the classUDF member function as a static function, so the last line of the code above results in a compilation error!

推荐答案

这是不可能做到的 - 在 C++ 中,您必须使用自由函数或静态成员函数,或者(在 C++11 中)一个 lambda无需捕获即可获取函数指针.

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 允许你创建嵌套函数,它可以做你想做的事,但只能在 C 中.它使用所谓的蹦床来做到这一点(基本上是动态生成的小块代码).可以使用此功能,但前提是您将一些调用 externalFunction 的代码拆分为单独的 C 模块.

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.

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

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

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

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

它真的很糟糕的代码,但我担心你会因为你的 externalFunction 这样糟糕的设计而走运.

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

相关文章