簡體   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