C++ 将指向成员函数的指针强制转换为普通指针
目前,我有一个这样的类,为简单起见缩短了:C++ 将指向成员函数的指针强制转换为普通指针,c++,pointers,casting,C++,Pointers,Casting,目前,我有一个这样的类,为简单起见缩短了: class MyClass { public: MyClass(); void* someFunc(void* param); } 现在我需要调用这类函数(不是任何类的成员,不幸的是,无法更改它),但无论如何我都需要调用它: void secondFunc(int a, int b, void *(*pCallback)(void*)); 现在我需要传递一个实例的someFunc的地址 A不起作用的样本:
class MyClass {
public:
MyClass();
void* someFunc(void* param);
}
现在我需要调用这类函数(不是任何类的成员,不幸的是,无法更改它),但无论如何我都需要调用它:
void secondFunc(int a, int b, void *(*pCallback)(void*));
现在我需要传递一个实例的someFunc的地址
A不起作用的样本:
MyClass demoInstance;
// some other calls
secondFunc( 1, 2, demoInstance::someFunc() );
我也尝试过这样的演员:
(void* (*)(void*)) demoInstance::someFunc;
reinterpret_cast<(void* (*)(void*))>(demoInstance::someFunc);
(void*(*)(void*)demoInstance::someFunc;
重新解释_cast(demoInstance::someFunc);
如何使用类的成员函数作为参数调用该函数,以便该类可以将其用作回调
如有任何意见或评论,我们将不胜感激。谢谢和问候
tobias您不能直接调用成员函数成员函数指针与函数指针的类型不同。
您需要以某种方式将其包装到兼容函数中。但是,如果外部函数(将函数指针作为参数的函数)不是可重入函数,并且没有提供额外的参数供函数指针使用,则无法传递成员函数操作的实例,因此,您实际上无法进行调用。之前没有看到关于无法更改第二个函数的部分
class MyClass
{
public:
MyClass();
void* someFunc(void* param);
};
void* callback(void*)
{
MyClass instance;
instance.someFunc(0 /* or whatever */);
}
void foo()
{
secondFunc( 1, 2, callback);
}
使用指向成员函数和对象的指针定义结构:
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);
做这件事有一种迂回的方法。由于C++名称被损坏,不能直接使用它来实现非静态函数。但是,由于非静态函数与C函数具有相同的签名,因此可以直接将它们用作回调。因此,对于非静态函数,可以使用静态函数包装器。详细解释了这个方法。 < P> C函数和C++成员函数之间的区别是C函数使用CDDEL调用约定,而成员函数使用这个调用调用约定(甚至不能取他们的地址!) 据我所知,您实际上希望
secondFunc()
调用类的特定实例的成员函数(我们称之为this
)。一个特定类的所有实例的成员函数的地址都是相同的。为了将指针传递到对象,需要一个侧通道。在这种情况下,它可能是静态变量。或者,如果需要MT支持,则必须使用线程本地存储(TLS)
这要求每个SomeFunc
类型的成员都有一个回调,但无论如何,您都需要一个调度程序。请参见此示例:
#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;
}
#包括
类MyClass
{
公众:
MyClass()
{
}
void*someFunc(void*param)
{
std::难道你必须提供一个实例;否则它是未定义的行为。你想做什么?什么指针作为它的参数传递到回调函数?如果你能以某种方式指定它,你应该能够创建一个struct Foo{MyClass*a;void*b;};
,然后使用void*MyCallback(void*Foo){Foo*Foo=static_cast(Foo);返回Foo->a->someFunc(Foo->b);}
作为回调函数。外部函数是库的一部分,我看到的唯一方法是拥有这些函数指针的静态数组……所有函数都是我自己定义的,调用时只调用相应对象的回调函数。这真的不可能吗?@Atmocreations:是的,这真的不可能。为了seei的目的ng为什么,请注意,除了void*
参数外,someFunc
还需要一个this
的值。它好像有两个参数,其中一个参数只能通过调用成员函数来提供。secondFunc
不进行成员函数调用,代码应该如何确定this
史提夫:我希望你不要这样说:“但是它在Python/Lisp/其他语言中起作用。”——“现在,C++C++已经关闭了。至少,这就是苹果告诉我的。”p@Jonathan:但是C++0x lambda与函数指针的类型不同,我认为块的类型也一样,不是吗(从未使用过clang)。因此,这里没有什么好处,而且它们不是“合适的”闭包,除非它们延长其upvalue的生存期。它总是有可以手动存储的闭包(引用)functor中有一大堆局部变量。首先谢谢。看起来很智能,稍后会检查细节。静态SomeFunc\u回调\u包装器如何访问实例obj
?