目前我有一类此类,为简单起见缩短了:
class MyClass {
public:
MyClass();
void* someFunc(void* param);
}
现在我需要调用这种类型的函数(不是任何类的成员,不幸的是无法更改),但无论如何我需要调用它:
void secondFunc(int a, int b, void *(*pCallback)(void*));
现在我需要传递一个实例的someFunc的地址。
不工作的样本:
MyClass demoInstance;
// some other calls
secondFunc( 1, 2, demoInstance::someFunc() );
我也尝试使用像:
这样的演员(void* (*)(void*)) demoInstance::someFunc;
reinterpret_cast<(void* (*)(void*))>(demoInstance::someFunc);
如何使用类'成员函数作为参数调用此函数,以便此函数可以将其用作回调?
任何想法或评论都表示赞赏。感谢致敬 托拜厄斯
答案 0 :(得分:8)
您无法直接调用成员函数。 成员函数指针与函数指针的类型不同。
你需要以某种方式将它包装在兼容的功能中。但是,如果您的外部函数(将函数指针作为参数的函数)不可重入并且不提供额外的参数供函数指针使用,则您将无法传递成员所使用的实例功能运作,所以你实际上无法拨打电话。
答案 1 :(得分:5)
C函数和C ++成员函数之间的区别在于C函数使用 cdecl 调用约定,而成员函数使用 thiscall 调用约定(并且你不能甚至拿他们的地址!)。
据我了解,您实际上希望secondFunc()
调用特定类的实例的成员函数(让我们称之为this
)。那么,特定类的所有实例的成员函数的地址是相同的。为了将指针传递给对象,您需要一个侧面通道。在这种情况下,它可以是静态变量。或者,如果您需要MT支持,则必须使用线程本地存储(TLS),
这需要每个SomeFunc
类型成员进行一次回调,但无论如何你都需要一个调度员。
答案 2 :(得分:1)
答案 3 :(得分:0)
class MyClass
{
public:
MyClass();
void* someFunc(void* param);
};
void* callback(void*)
{
MyClass instance;
instance.someFunc(0 /* or whatever */);
}
void foo()
{
secondFunc( 1, 2, callback);
}
答案 4 :(得分:0)
之前没有看到关于无法改变第二个功能的部分。
使用指向成员函数和对象的指针定义结构:
struct MyData {
MyStruct *myInstance;
(void *)(MyStruct::myFunction)(void *data);
void * dataPointer ;
}
创建一个可以调用正确方法的函数:
void *proxyFunc( MyData *data)
{
return (data->myInstance->*(data->myFunction))(data->dataPointer);
}
然后将函数2调用为:
MyData dataP = { someInstance, &MyStruct::someFunc, &dataPtr };
secondFunc(proxyFunc, &dataP);
答案 5 :(得分:0)
请参阅此示例:
#include <iostream>
class MyClass
{
public:
MyClass()
{
}
void* someFunc(void* param)
{
std::cout << "someFunc" << std::endl;
return (void*)0;
}
};
typedef void* (MyClass::*MemFun)(void*);
void secondFunc(int a, int b, MemFun fn)
{
MyClass* ptr = 0;
// This is dangerous! If the function someFunc do not operate the data in the class.
// You can do this.
(ptr->*fn)(0);
std::cout << "Call me successfully!" << std::endl;
}
int main()
{
secondFunc(1, 2, &MyClass::someFunc);
system("pause");
return 0;
}
答案 6 :(得分:0)
使用 union 很容易
#include <iostream>
using namespace std;
class Data {
public:
Data(const int data) : num(data) {
}
void printData() const {
printf("%d", this->num);
}
private:
int num;
};
union Test {
decltype(&Data::printData) member_fun;
void (* normal_function)(...);
};
int main() {
Test t;
t.member_fun = &Data::printData;
Data data(10);
(*t.normal_function)(&data);
}