问题:有没有办法将指向成员函数的指针转换为 C++ 中的 intptr_t?
已知因素:
- 我知道成员函数指针很特别
- 我知道成员函数传递隐藏的“this”参数(__thiscall)。
- 我知道 sizeof(member function pointer) > sizeof(intptr_t) 在某些情况下,在这个问题中我只谈论可能的情况,即在我的情况下 sizeof(member function pointer) == sizeof(intptr_t) .
- 最后我知道将指针转换为 intptr_t 不是一个好的模式。
示例代码:
class test // No inheritance, in the case I need
{
public:
void func(); // No virtual, or any special modifiers in the case I need
};
void main2()
{
intptr_t p = &test::func;
};
我知道一个解决方法来做这个演员,但我不喜欢它,因为它需要一个临时变量:
void my_way()
{
intptr_t p;
auto t = &test::func; // Temp variable, I don't like the fact I need to use it, but I have no other way for now
p = *reinterpret_cast<intptr_t*>(&t);
};
所以问题是如何将技巧内联作为右值表达式,没有临时变量(并且没有相同的 memcpy)。
例子:
reinterpret_cast<??>(???_cast<??>(???_cast<??>( &test::func )))
(我不在乎表情会多么美丽)。
-------------------------(下面是关于为什么的一些想法,而不是问题)------------- ------------------
这个网站上有一些类似的主题,但他们大多都在谈论“你为什么这样做?”或“你为什么需要这个?”,谈论这个解决了提问的人的问题,但不是为了我。
为什么我需要这个员工:我正在编写某种任务,我决定实现我自己的动态链接机制。可以有几个特定的应用程序。
就我而言 - 动态链接机制 - 我想将指向函数的指针传递给另一个模块。我有一个类和一个接口作为一个单独的结构(我知道,有相同方法的库)。众所周知,使用这种机制的所有类都是普通的(根本没有继承,所以没有虚拟等)。所有这些都在 x86 32 位或最多在 64 个 Windows 上运行,由 MSVC 2012 编译。由于接口与类完全隔离,它使用指针数组。Lib 将数组传递给主机进程。在主机进程中我有这个......这甚至不是一个“问题”,但仍然:
inline int my_interface::func_name(int param)
{
decltype(&interface_name::func_name) temp;
*((intptr_t*)&temp) = reinterpret_cast<interface_name::funcs*>(interface_desc->funcs)->func_name;
return (reinterpret_cast<decltype(this)>(object)->*temp)(param);
};
这是一个内联函数,所以我希望它尽可能小,如果可能的话,我想消除“temp”,因为我不确定编译器是否会正确消除它,即使进行了所有优化。
其他应用程序(假设): - 如果我想用特定的保护来保护我的成员函数所在的内存页面怎么办。WinAPI 为我提供了一种方法,但它需要页面的地址。对于正常功能,这样做没有问题,但对于成员 - 仅使用我描述的 WA?或者有什么办法?- 如果我想在运行时修补图像怎么办?即找到一些 const 并用另一个替换它?运行时修补至少有几个原因:2.1 动态链接重定位过程,2.2 代码混淆。
这只是为了说明 - 读者经常问“为什么”,我不想讨论为什么,因为在我看来可以有很多应用程序,所有这些都不是针对新手,而是更多用于安全人员等......
我特此要求不要讨论“为什么这样做?”,“为什么不使用 dll/boost/其他库/其他语言的现有机制?” 在这个线程中。