将指向成员函数的指针强制转换为intptr_t
Cast pointer to member function to intptr_t
问题:有没有办法将指向成员函数的指针转换为C++中的intptr_t?
已知因素:
- 我知道成员函数指针是非常特别的
- 我知道成员函数传递隐藏的"this"参数(__thiscall)。
- 我知道在某些情况下sizeof(成员函数指针)>sizeof(intptr_t),在这个问题中,我只谈论可能的情况,即在我的案例中 sizeof(成员函数指针) == 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?还是有办法?- 如果我想在运行时修补映像怎么办?即找到一些常量并用另一个替换它?运行时修补可能至少有几个原因:2.1 动态链接重定位过程,2.2 代码混淆。
这只是一个注释 - 读者经常问"为了什么",我不想讨论为什么,因为在我看来可以有很多应用程序,所有这些应用程序都不是针对新手,而是针对安全人员等......
我在此要求不要在这个线程中讨论"为什么要这样做?","为什么不使用dll/boost/其他库/其他语言的现有机制?
不,规范不允许将函数指针或成员指针强制转换为intptr_t。 这样做的原因是您可能需要多个intptr_t的数据来描述它们。 例如,gcc 上的成员指针长度为 3 intptr_t,MSCV 的长度为 1 到 4 intptr_t。 其中大部分用于处理虚拟功能。
在某些旧硬件(C++支持)上,指针实际上也比函数指针小。 这种情况发生在小型系统上,您可能只需要指向 8 位内存结构,但程序会加载到 16 位程序内存空间中。
大多数情况下,您尝试使用的这种模式用于创建委托:永久绑定到特定对象的成员函数指针。 这可以通过 2 个 int 指针和一个包装函数来完成
struct Delegate
{
intptr_t obj; // I'll use intptr_t here, but often this is void*
intptr_t func;
};
// you need one of these for each type of mfp you use
static void callT_Test(intptr_t obj)
{
T* realObj = reinterpret_cast<T*>(obj);
realObj->test();
}
// constructing a delegate to call test on t
Delegate d;
d.obj = reinterpret_cast<intptr_t>(&t);
d.func = &callT_Test;
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++到 C# 转换与 IntPtr
- 将 IntPtr 转换为对象 C#
- 将IntPtr转换为c#结构指针
- c++ /CLI双指针类型转换为ref IntPtr,用于c#访问