代码之家  ›  专栏  ›  技术社区  ›  laalto

使用裸函数指针调用成员函数

  •  -2
  • laalto  · 技术社区  · 14 年前

    thiscall 电话会议。

    背景:我在一个共享库中动态查找符号,获得一个工厂函数指针和一个指向我要调用的某个成员函数的指针。成员函数本身不是虚拟的。我无法控制共享库,我只有二进制文件。

    例子:

    typedef void * (*GenericFptr)();
    GenericFptr lookup(const char *);
    
    class CFoo;
    
    GenericFptr factoryfn(lookup("CFoo factory function"));
    CFoo *foo = reinterpret_cast<CFoo *>(factoryfn());
    
    GenericFptr memberfn(lookup("CFoo member function"));
    
    // now invoke memberfn on foo
    

    目前我正在使用 union

    class CFoo {
      public: 
      void *dummy() { return 0; }
    };
    typedef void * (CFoo::*FooMemberPtr)();
    
    union {
      struct {
        // compiler-specific layout for pointer-to-member
        void *x, *y;
        GenericFptr ptr;
      } fnptr;
      FooMemberPtr memberfn;
    } f;
    
    f.memberfn = &CFoo::dummy; // init pointer-to-member
    f.fnptr.ptr = memberfn;    // rewrite pointer
    
    void *result = (foo->*f.memberfn)();
    
    4 回复  |  直到 14 年前
        1
  •  1
  •   Mark B    14 年前

    不幸的是,成员函数指针比标准函数指针具有更多的信息,当您得到标准函数指针时,将其转换为成员函数指针实际上是在无中生有地生成额外的数据。

    我不认为有任何可移植的方法来做你正在尝试的事情,尽管如果工会看来有效,你可能会侥幸逃脱。同样,您需要知道这些方法对于您希望用于构建bode的每个编译器的表示和调用约定。

    如果你知道成员函数的名字,为什么你不能 foo->dummy() 例如?否则,要么lookup函数需要提供一个完整的成员函数指针,要么库必须提供一个具有普通函数的C包装器接口,该函数可以将该指针传递给它。

        2
  •  2
  •   AProgrammer    14 年前

    如果您希望具有可移植性,最简单的方法是让库提供包装函数来执行成员调用。

        3
  •  0
  •   Alexandre C.    14 年前

    this 参数通常不起作用,因为必须考虑虚拟方法、多重继承和虚拟继承。

    http://www.codeproject.com/KB/cpp/FastDelegate.aspx

    http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx

        4
  •  0
  •   Community CDub    7 年前

    根据下面的答案,它在GCC中是可行的,但不可移植:

    https://stackoverflow.com/a/5067992/705086