将对象的方法指针传递给接受[静态方法指针/全局函数]指针的函数

Posted

技术标签:

【中文标题】将对象的方法指针传递给接受[静态方法指针/全局函数]指针的函数【英文标题】:Passing object's method pointer to function that accept [static method pointer / global function ] pointer 【发布时间】:2013-12-13 10:54:08 【问题描述】:

我有方法

typedef void
(* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);

JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);

我想传递对象的方法而不是静态方法

JS_SetErrorReporter(cx,this->Reporter);//Failed ! 

其中 Reporter 是对象的方法(不是静态的)

JS_SetErrorReporter(cx,Reporter); //Passed 

其中 Reporter 是静态方法,声明为

static void SomeClass::reportError(JSContext *cx, const char *message, JSErrorReport *report) 

【问题讨论】:

使用&SomeClass::reportError 那么,this->Reporter 是完全错误的语法(即使对于成员函数指针)。静态方法无论如何都不知道this 你可以做的是提供一个静态方法,它以某种方式从上下文中获取this 指针。我不知道JSContext 是否提供了一些void* userData; 成员,可以用于此。 【参考方案1】:

你想使用一个成员函数指针,你必须得到正确的语法,(不是微不足道的) 对于一个无聊的函数,获取并返回一个 int,那就是:

声明一个变量(也适用于参数):

int (SomeClass::*my_memfunc_ptr)(int);

分配一个变量:

 my_memfunc_ptr = &SomeClass::some_member_func;

调用:

  SomeClass *x = new SomeClass;
  int n = (x->*my_memfunc_ptr)(6);

我把这个适应你的非 int 用途留给你。

【讨论】:

【参考方案2】:

你不能直接做。因为要调用一些非静态函数,你必须有 this 指针,但你不要将它传递给 JS_SetErrorReporter 函数。

两种可能的解决方案:

    更改JSErrorReporter 签名以接受void * 类型的+1 参数并在那里传递this 指针。

    创建一个包装函数作为一个全局函数,它也知道需要this指针。

【讨论】:

【参考方案3】:

避免静态函数很容易使用 __closure 函数指针来代替:

//---------------------------------------------------------------------------
class C2
    
    public:
    void callback1()                      // your member function to pass to ...
    ;

class C1                                    // some class with member function pointer usage
    
    public:
    void (__closure *callback1)();          // member function pointer
    C1()  callback1=NULL;                 // constructor
    void do_something()                     // some function with use of callback1
        
        if (callback1) callback1();
        
    ;

void some_function(void (__closure *f)())   // some function with member function parameter usage
    
    if (f) f();
    

void main()
    
    C1 c1;
    C2 c2;
    c1.callback1=c2.callback1;
    c1.do_something();
    some_function(c1.callback1);
    some_function(c2.callback1);
    
//---------------------------------------------------------------------------

[编辑 1]

但正如 RichardPlunkett 概述的 __closure 它仅适用于 borland/embarcadero 编译器 对于 VC/GCC/Intel ... 编译器,您需要一种解决方法 那里有一些。 看起来人们更喜欢名为 boost 库的东西 在这里我找到了一个__closure 模仿的例子http://www.rsdn.ru/forum/cpp/3078740.flat 它是俄文的,但即使对于我们 azbuka 非读者来说,源代码也很清楚......

【讨论】:

那是编译器特定的扩展不是吗? 如果你是对的,我认为这是理所当然的,因为我主要在 borland 编写代码,所以我没有想到 :(objectmix.com/c/398370-how-translate-__closure-into-pure-c.html

以上是关于将对象的方法指针传递给接受[静态方法指针/全局函数]指针的函数的主要内容,如果未能解决你的问题,请参考以下文章

c ++:将指针传递给基类时访问派生类方法?

将指针传递给静态方法

Java - 将指向对象的指针传递给函数

C++成员函数指针指向全局函数指针

向模板类传递通用方法的指针。

将const引用/指针传递给类进行存储的首选方法,而不是复制引用的对象