简体   繁体   English

将指向成员函数的指针转换为普通指针

[英]Cast pointer to member function to normal pointer

Currently I have a class of this kind, shortened for simplicity:目前我有一个这样的类,为简单起见缩短:

class MyClass {
    public: 
        MyClass();
        void* someFunc(void* param);
}

Now I need to call a function of this kind (not member of any class and which I unfortunately cannot change ) but which I need to call anyway:现在我需要调用这种函数(不是任何类的成员,不幸的是我无法更改)但无论如何我都需要调用它:

void secondFunc(int a, int b, void *(*pCallback)(void*));

Now I need to pass the address of someFunc of an instance.现在我需要传递一个实例的 someFunc 的地址。

A not working sample:一个不工作的样本:

MyClass demoInstance;
// some other calls
secondFunc( 1, 2, demoInstance::someFunc() );

I've tried also with casts like:我也试过像这样的演员:

(void* (*)(void*)) demoInstance::someFunc;
reinterpret_cast<(void* (*)(void*))>(demoInstance::someFunc);

How can I call this function with a class' member function as parameter so that this one can use it as callback?如何使用类的成员函数作为参数调用此函数,以便此函数可以将其用作回调?

Any idea or remark is appreciated.任何想法或评论表示赞赏。 Thanks and regards tobias感谢并问候托比亚斯

You can't call the member function directly.不能直接调用成员函数。 Member function pointers are not the same type as function pointers.成员函数指针与函数指针的类型不同。

You'll need to wrap it in a compatible function somehow.您需要以某种方式将其包装在兼容的函数中。 However, if your outer function (the one taking the function pointer as an argument) is not re-entrant and does not supply an extra argument for use by the function pointer, you won't be able to pass the instance upon which the member function operates, so you won't actually be able to make the call.但是,如果您的外部函数(将函数指针作为参数的函数)不是可重入的,并且不提供供函数指针使用的额外参数,则您将无法传递成员所在的实例函数运行,因此您实际上无法拨打电话。

The difference between a C function and a C++ member function is that C function uses cdecl calling convention, while member functions uses thiscall calling convention (and you can't even take their address!). C 函数和 C++ 成员函数的区别在于,C 函数使用cdecl调用约定,而成员函数使用thiscall调用约定(你甚至不能取它们的地址!)。

As I understand, you actually want that secondFunc() to call the member function of a particular instance of class (let's call it this ).据我了解,您实际上希望secondFunc()调用类的特定实例的成员函数(我们称之为this )。 Well, addresses of member functions of all the instances of a particular class are the same.那么,一个特定类的所有实例的成员函数的地址都是相同的。 In order to pass the pointer to the object, you will need a side channel.为了将指针传递给对象,您将需要一个侧通道。 In this case it could be static variable.在这种情况下,它可能是静态变量。 Or, if you want MT support, you'll have to use Thread Local Storage (TLS),或者,如果您想要 MT 支持,则必须使用线程本地存储 (TLS),

This requires one callback per SomeFunc -type member, but you would need a dispatcher somewhere anyway.这需要每个SomeFunc类型成员一个回调,但无论如何您都需要一个调度程序。

There is a round about way of doing it.有一种方法可以做到这一点。 Since C++ names are mangled you can't directly use it for non-static functions.. however since non-static functions have the same signatures as C functions, you can directly use them as callbacks.由于 C++ 名称被破坏,您不能将其直接用于非静态函数。但是,由于非静态函数与 C 函数具有相同的签名,因此您可以直接将它们用作回调。 So for non-static functions, you can have static function wrappers.因此,对于非静态函数,您可以使用静态函数包装器。 This page explains this approach in detail.页面详细解释了这种方法。

class MyClass 
{
public: 
    MyClass();
    void* someFunc(void* param);
};

void* callback(void*)
{
    MyClass instance;
    instance.someFunc(0 /* or whatever */);
}

void foo()
{
    secondFunc( 1, 2, callback);
}

Didn't see the part about not being able to change the second function before.之前没有看到关于无法更改第二个功能的部分。

Define a structure with pointers to the member function and to the object:定义一个带有指向成员函数和对象的指针的结构:

struct MyData {
   MyStruct  *myInstance;
   (void *)(MyStruct::myFunction)(void *data);
   void * dataPointer ;
}

Create a function that can invoke the proper method:创建一个可以调用正确方法的函数:

void *proxyFunc( MyData *data)
{
  return (data->myInstance->*(data->myFunction))(data->dataPointer);
}

Then call the function 2 as:然后调用函数 2 为:

MyData  dataP = { someInstance, &MyStruct::someFunc, &dataPtr };
secondFunc(proxyFunc, &dataP);

See this sample:请参阅此示例:

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

use union can be easy使用 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将派生类中的成员函数的指针强制转换为抽象成员函数的指针 - cast a pointer to member function in derived class to a pointer to abstract member function 将成员函数的指针转换为C函数的指针是一种好习惯吗 - Is it good practice to cast a pointer to a member function as a pointer to a C function 我可以合法地将成员函数指针转换为函数指针吗? - Can I legally cast a member function pointer to a function pointer? reinterpret_cast 成员函数指针指向 void(*&amp;)() - reinterpret_cast member function pointer to void(*&)() 将指向成员函数的指针转换为intptr_t - Cast pointer to member function to intptr_t 重载成员函数指针的演员转换助手 - cast helper for overloaded member function pointer C ++:闭包传递成员函数作为普通函数指针 - C++: closure to pass member function as normal function pointer 将指向struct的指针强制转换为指向该结构的唯一成员的指针 - Cast a pointer to struct to a pointer to the only member of that struct 将指针和成员指针连接到函数指针 - Joining a pointer and member pointer into a function pointer 将一个指向成员的指针函数转换为同一个类的另一个指针 - Cast one pointer-to-member-function to another of same class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM