![](/img/trans.png)
[英]Using a C++ class member function as a C callback function
[英]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::function<void(double*)> stored = std::bind(&myClass::classUDF, boost::ref(myClassObj))
(假設編譯器現在支持C ++ 0x。我確定Boost在某處有一個boost :: function <>)
沒有這樣的魔法,你需要指向成員函數的指針語法:
編輯澄清去提意見,顯然這只能當且僅當你有超過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);
}
// 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.