2

我正在使用 Windows 中的 API,该 API 本质上使用 UINT_PTR(对象的地址)进行回调,并提供获取有关这些对象的更多信息的方法。

我有一个集合,其中 MyObject 是我的类,其中包含我关心的信息(对这个问题不重要):

std::unordered_map<UINT_PTR,MyObject*> objectMap;

我有一个会被多次调用的函数。在某些情况下,需要修改 API 提供的地址。我在我的收藏中找不到任何修改过的 UINT_PTR。例如:

void CallbackHandler::APICallback( UINT_PTR address )
{
    UINT_PTR collectionKey = address;

    if( SomeCondition() )
    {
        collectionKey -= 0x10;
    }

    if( objectMap.count( collectionKey ) == 1 )
    {
      // Write message to log, condition we care about occurred
    }
    else
    {
      // Do some info gathering and evaluation, possibly adding collectionKey to objectMap
    }
}

例如,第一次调用上述函数时将“0xFF4116A8”添加到集合中。第二次调用该函数时,address="0xFF4116B8" 和 SomeCondition() 恰好为真,所以我们减去 0x10 再次得到“0xFF4116A8”。但是, objectMap.count("0xFF4116A8")==1 不是真的......但是当我记录集合的内容时,“0xFF4116A8”确实在那里。

我怀疑我在尝试对 UINT_PTR 进行算术运算或对 unordered_map 的行为做出错误假设时犯了某种基本错误。我在这里犯了什么错误,修改 UINT_PTR 然后在集合中查找它的正确方法是什么?

4

2 回答 2

0

向大家道歉!

事实证明问题出在代码的其他地方。代码更像:

void CallbackHandler::APICallback( UINT_PTR address, SOME_TYPE_INFO typeInfo )
{
    UINT_PTR collectionKey = GetAddressForType( address, typeInfo );

    // Rest of the code the same...

GetAddressForType 在哪里做:

UINT_PTR CallbackHandler::GetAddressForType( UINT_PTR address, SOME_TYPE_INFO typeInfo )
{
  UINT_PTR objectId = 0;

  switch( typeInfo )
  {
  case ELEMENT_TYPE_STRING:
    objectId = *(PUINT_PTR) address;
    break;
  case ELEMENT_TYPE_CLASS:
    objectId = address;
    break;
  case ELEMENT_TYPE_I:    // fall through - intptr
  case ELEMENT_TYPE_U:    // fall through - uintptr
  case ELEMENT_TYPE_PTR:  // pointer
    objectId = *(UINT *) address; // This was the problem right here. Should be *(PUINT_PTR) cast.
    break;
  }

  return objectId;
}

相反,我需要使用与字符串类型相同的 *(PUINT_PTR) 强制转换。

感谢大家的帮助。

于 2013-05-07T16:01:47.310 回答
0

我不能用这个重现你的例子:

#include <unordered_map>

struct MyObject{};

int main(int argc, _TCHAR* argv[])
{
    std::unordered_map<UINT_PTR,MyObject*> objectMap;
    UINT_PTR x = 0xFF4116A8;
    objectMap[x] = nullptr;
    UINT_PTR y = 0xFF4116B8;
    y -= 0x10;
    auto c = objectMap.count(y);    // c == 1
    return 0;
}

你是在 64 位机器上吗?您是否有可能在未提供的代码中进行符号扩展指针算术?

于 2013-05-07T14:39:37.540 回答