使用裸函数指针调用成员函数
如果您有一个对象和一个指向成员的裸函数指针,那么调用成员函数的最佳方法是什么?本质上我想用 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)();
What's the best way to call a member function if you have an object and a bare function pointer pointing to the member? Essentially I want to call the function pointer with thiscall
calling convention.
Background: I'm looking up symbols in a shared library dynamically, obtaining a factory function pointer and a pointer to a certain member function I want to call. The member function itself is not virtual. I have no control over the shared library, I just have the binary.
Example:
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
Currently I'm using an union
to convert the function pointer to a pointer to member function. It's ugly and creates dependencies to compiler implementation details:
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)();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
指向成员函数的指针不能存储在指向函数的指针中,因为它需要更多信息(例如,在多重继承的情况下,可能必须在调用之前将偏移量应用于此)。因此,您不能不了解实现细节。
如果您想要可移植,最简单的方法是让您的库提供执行成员调用的包装函数。
A pointer to member function can't be stored in a pointer to function because it needs more information (for instance in case of multiple inheritance an offset may have to be applied to this before the call). So you can't do without knowledge of implementation details.
If you want to be portable, the easiest is for your library to provide wrapper functions doing the member call.
不幸的是,成员函数指针比标准函数指针具有更多信息,当您获得标准函数指针时,将其转换为成员函数指针实际上会尝试凭空生成额外的数据。
我认为没有任何可移植的方法来完成您正在尝试的事情,尽管如果工会似乎有效,您可能会逃脱惩罚。同样,您需要了解您希望用于构建波特的每个编译器的这些方法的表示和调用约定。
如果您知道成员函数的名称,为什么不能直接执行
foo->dummy()
呢?否则,要么查找函数需要提供完整的成员函数指针,要么库必须提供一个 C 包装器接口,其中包含可以传递 this 指针的普通函数。Unfortunately a member function pointer has more information than a standard function pointer, and when you get the standard function pointer, converting it to a member function pointer would effectively be trying to generate extra data out of thin air.
I don't think there's any portable way to do what you're attempting, although if the union appears to work you could probably get away with that. Again, you would need to know the representation and calling convention for these methods for each compiler you wish to use to build the bode.
If you know the member function's name, why can't you just do
foo->dummy()
for example? Otherwise either the lookup function needs to provide a full member function pointer or the library would have to provided a C wrapper interface with normal functions to which a this pointer can be passed.以下两个链接提供了见解并可能提供解决方案。请注意,使用
this
参数调用成员函数指针通常不起作用,因为您必须考虑虚拟方法、多重继承和虚拟继承。http://www.codeproject.com/KB/cpp/FastDelegate.aspx
http://www.codeproject.com/KB/cpp/ImpossouslyFastCppDelegate.aspx
The following two links provide insight and possibly a solution. Note that calling a member function pointer with a
this
argument usually don't work, since you must take into account virtual methods, multiple and virtual inheritance.http://www.codeproject.com/KB/cpp/FastDelegate.aspx
http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx
根据下面的答案,它在 GCC 中是可行的,但不可移植:
https://stackoverflow.com/a/5067992/705086
According to the answer below it is doable in GCC, but not portable:
https://stackoverflow.com/a/5067992/705086