2014-06-25 124 views
1

有人可以解释和帮助我在这里请。 可以说我有这样的功能,其中lpData持有指向我想要的数据的指针。从LPVOID检索字符串

void foo(LPVOID lpData) { 

} 

什么是中检索正确的方法。这工作,但我在最后

void foo(LPVOID lpData) { 
    LPVOID *lpDataP = (LPVOID *)lpData; 
char *charData = (char*)lpDataP; 
    //i log charData.... 
} 

我宁愿使用字符串变得怪异字符,但我不知道如何来检索数据,我只是得到空指针错误,当我尝试使用字符串。 lpData持有一个指针吗? (但我的功能是lpData不是* lpData),所以它不工作?我做这一切都错了吗?

string *datastring = reinterpret_cast<std::string *>(lpData); 

是即时通讯尝试。

+4

'LPVOID'已经是'void *'了。如果你传递一个指向'std :: string'的指针,只需使用'static_cast '。 – chris

+2

为什么从'LPVOID'('void *',任何指针)转换为'LPVOID *'('void **',指向任何指针的指针)? – abarnert

回答

2

这工作,但我在最后得到怪异字符

这意味着,您的字符串ISN 'null null-terminated - 也就是说,它没有NUL字节(0)标记字符串的结尾。 *当您记录一个C字符串(char *)时,它会一直记录字符,直到找到一个NUL。如果字符串末尾没有一个字符串,它将继续通过随机内存直到找到一个(或者直到您遇到页面错误并崩溃)。这不好。而且没有办法解决它;一旦你失去了长度,就没有办法让它恢复原状。

但是,未终止的字符串及其长度可能会有用。许多函数的长度可以与char *一样,作为额外的参数(例如,string构造函数)或其他方式(例如printf格式字符串中的宽度说明符)。所以,如果你取长度,并且只调用也占用长度的函数 - 或者只是创建一个以null结尾的副本并使用它,那么你很好。所以:

void foo(LPVOID lpData, int cchData) { 
    string sData(static_cast<const char *>(lpData), cchData); 
    // now do stuff with sData 
} 

同时,从LPVOID铸造(又名void *,又名指针到任何东西),以LPVOID *(又名void **,又名指针,指针到任何东西),以便然后转换为char *(指针TO-字符)是错误的(并且应该在第二次播放时给你一个编译器警告;如果你得到警告并忽略它们,不要这样做!)。此外,使用现代演员而不是C型演员阵容通常会更好,并且在没有缺陷的情况下最好保持正确的阵容;它只是让读者更加明确,面对未来的维护更安全。

最后:

string *datastring = reinterpret_cast<std::string *>(lpData); 

这几乎肯定是错的**的LPVOID只是在一串字符的指点。你说你想要将这些角色解释为它们是一个string对象。但是一个string对象是一些标题信息(可能是长度和容量等)以及指向一堆字符的指针。治疗一个与其他会导致垃圾或崩溃。***


*是的,你正在使用C++,不C,但char *是一个“C字符串”。

**如果你确实有,你已经更让某处string对象,你在LPVOID藏一个指向对象,现在已经取回它(例如,用SetWindowLongPtr/GetWindowLongPtr),然后从铸LPVOIDstring *会有意义。但我怀疑你在做什么。 (如果你是,那么你不需要reinterpret_cast。的void *整个的一点是,它没有解释,所以没有什么距离。只需使用static_cast重新解释。)

***或者说,最糟糕的是,它似乎可以工作,但随后会导致难以遵循的崩溃或腐败。某些标准的C++库使用特殊的分配器将标题放在字符之前,并返回指向第一个字符的指针,以便可以在char *可以使用的任何位置使用string。在string类中,每种方法都必须将指针向后隐藏起来;例如,而不是仅仅说m_length它必须做类似static_cast<_string_header *>(this)[-1]->m_length。但反过来也行不通 - 如果你只有一堆字符,而不是一个对象,那么这个软件将读取在字符之前分配的任何字节,并尝试将它们解释为一个整数,所以你可能会认为你有一个长度为0的字符串,或者182423742341241243.

+0

谢谢你解释得很好,我的错误很糟糕。 – nicwhitts

0

至少有两种方式:

void foo(LPVOID lpData) 
{ 
    char *charData = (char*)lpData; 
    //i log charData.... 
} 

void foo(LPVOID lpData) 
{ 
    char *charData = static_cast<char*>lpData; 
    //i log charData.... 
}