-3

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

4 回答 4

2

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

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

于 2010-06-30T13:11:09.037 回答
1

不幸的是,成员函数指针比标准函数指针具有更多信息,当您获得标准函数指针时,将其转换为成员函数指针实际上会试图凭空生成额外的数据。

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

如果您知道成员函数的名称,为什么不可以举个foo->dummy()例子呢?否则,查找函数需要提供一个完整的成员函数指针,或者库必须提供一个 C 包装接口,其中包含可以传递 this 指针的普通函数。

于 2010-06-30T13:29:04.090 回答
0

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

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

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

于 2010-06-30T13:14:20.133 回答
0

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

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

于 2014-03-21T09:11:34.783 回答