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

时间:2010-06-30 12:54:32

标签: c++ function-pointers member-function-pointers

如果有一个对象和一个指向该成员的裸函数指针,调用成员函数的最佳方法是什么?基本上我想用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 个答案:

答案 0 :(得分:2)

指向成员函数的指针不能存储在指向函数的指针中,因为它需要更多信息(例如,在多次继承的情况下,可能必须在调用之前对此应用偏移量)。所以你不能不了解实施细节。

如果您想要可移植,最简单的方法是让您的库提供执行成员调用的包装函数。

答案 1 :(得分:1)

不幸的是,成员函数指针比标准函数指针有更多的信息,当你得到标准函数指针时,将它转换为成员函数指针实际上会试图凭空创建额外的数据。

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

如果您知道会员功能的名称,为什么不能这样做foo->dummy()?否则,查找函数需要提供一个完整的成员函数指针,否则库必须提供一个带有普通函数的C包装器接口,该指针可以传递给它。

答案 2 :(得分:0)

以下两个链接提供了洞察力并可能提供解决方案。请注意,调用带有this参数的成员函数指针通常不起作用,因为您必须考虑虚方法,多重和虚拟继承。

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

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

答案 3 :(得分:0)

根据下面的答案,它在GCC中是可行的,但不是便携式的:

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