2013-05-07 40 views
2

我正在使用Windows中的API,基本上使用UINT_PTR(对象的地址)进行回调,并提供获取有关这些对象的更多信息的方法。C++:在unordered_map中查找已修改的UINT_PTR <UINT_PTR,Object *>

我有一个集合,其中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”添加到收藏。第二次调用该函数时,地址=“0xFF4116B8”,SomeCondition()恰好为真,因此我们再减去0x10以获得“0xFF4116A8”。然而,objectMap.count(“0xFF4116A8”)== 1是不正确的...但是当我记录集合“0xFF4116A8”的内容确实在那里。

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

+0

如果从。减去0x10的一个UINT-PTR您ADRESS将0x40的递减而不是0x10的 – 2013-05-07 13:26:24

+0

我有一个问题:为什么不安排事情,所以在uintptr_t的点为myObject实例,而不是额外的层间接提供的地图? – 2013-05-07 13:45:12

+0

@vlad_tepesch请注意,尽管名称不同,UINT_PTR是一种Windows类型,定义为unsigned __int64,而不是UINT *。所以算术是正确的 – 2013-05-07 14:40:55

回答

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)铸造为字符串类型。

感谢您的帮助。

+0

是 - 其中一条评论暗示了UINT_PTR(!= UINT *)的混淆。许多开发者已经绊倒了它,包括我自己在内。 – 2013-05-07 17:06:20

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位的机器上?您是否有可能在未提供的代码中进行符号扩展指针算术?

+0

我在64位机器上,但除了 - = 0x10之外,我没有做任何算术运算。 – 2013-05-07 15:49:47

相关问题