【问题标题】:How to get the "raw" ptr of a lambda *capture* function如何获取 lambda *capture* 函数的“原始”ptr
【发布时间】:2021-06-06 21:10:13
【问题描述】:

我想使用 lambda 捕获制作 C++ 程序集挂钩,但为此我需要获取 lambda capture 函数的指针。

类似这样的:

int val0 = 42;
auto lambdaCap = new auto([&]() -> int { return val0++; });
uint64_t pLambdaFn = static_cast<uint64_t>(&decltype(*lambdaCap)::operator()); // need this

我理解 lambda 函数捕获看起来像是一个带有仿函数的类的实例,但我想获取 lambda::operator() 的静态地址。在内存中,“lambdaCap”只是 lambda 中使用的变量成员的一个指针。

谢谢

【问题讨论】:

  • 您可能无法将指向成员函数的指针存储在普通指针中(成员指针的大小可能比普通指针大)。

标签: c++ assembly reverse-engineering


【解决方案1】:

&amp;decltype(*lambdaCap)::operator()) 无效,因为decltype(*lambdaCap) 实际上是对闭包类型的左值引用。

相反,std::remove_pointer_t&lt;decltype(lambdaCap)&gt; 会为您提供闭包类型本身。所以你可以写&amp;std::remove_pointer_t&lt;decltype(lambdaCap)&gt;::operator()来获取闭包类型的函数调用操作符对应的指向成员函数的指针。

但是,该表达式的类型为int (T::*)(),无法转换为整数类型。您可以按原样存储它,并使用指向闭包类型实例的指针(例如lambdaCap 本身)调用它,但不能将其转换为uint64_t。无法将指向非静态成员的指针转换为整数类型,无论是使用 static_castreinterpret_cast 还是任何其他类型。

【讨论】:

  • 谢谢!像这样组合auto pLambdaFn = &amp;std::remove_pointer_t&lt;decltype(lambdaCap)&gt;::operator(); uint64 lambdaFnAddr = *(uint64*)&amp;pLambdaFn; 在 MSVC x64 上获取原始地址可以正常工作(ptr cast 在其他编译器/设置上可能不安全)
  • @LowelSassi 我不知道您所说的“原始地址”是什么意思,但如果您知道如何获得对您有用的值,我很高兴能提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-06
  • 2021-05-02
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
相关资源
最近更新 更多