从LPVOID中检索字符串

时间:2014-06-25 03:16:10

标签: c++ string

请有人解释并帮助我。 假设我有这样的函数,其中lpData包含指向我想要的数据的指针。

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);

是我的尝试。

2 个答案:

答案 0 :(得分:2)

  

这样可行,但我最后得到了奇怪的字符

这意味着您的字符串不是以空值终止的 - 也就是说,它没有标记字符串结尾的NUL字节(0)。

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

但是,未终止的字符串及其长度可能很有用。许多函数可以使用char *旁边的长度作为额外参数(例如,string构造函数)或其他(例如,printf格式字符串中的宽度说明符)。

所以,如果你取长度,只调用也需要长度的函数 - 或者只是制作一个空终止的副本并使用它 - 你没事。所以:

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

同时,从LPVOID(又名void *,也就是指向任何指针)转换为LPVOID *(又名void **,也就是指针指向任何东西的指针)然后转换为char *(指向字符的指针)是错误的(并且应该在第二次投射中给你一个编译器警告;如果你收到警告并忽略它们,那就不要这样做!)。另外,使用现代模型代替C风格的模型通常会更好,而且当没有下方时,最好是const-correct;它只是让读者更清楚,面对未来的维护更安全。

最后:

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

这几乎肯定是错的。** LPVOID只是指着一堆字符。您是说要将这些字符解释为string个对象。但是string对象是一些标题信息(可能是长度和容量等)加上指向一堆字符的指针。将另一个视为另一个将导致垃圾或崩溃。***


*是的,您使用的是C ++,而不是C,但char *是“C字符串”。

**如果你实际上有一个string对象,你在某个地方保持活着,你在LPVOID中藏了一个指向该对象的指针,现在已经检索到了它(例如,用{{ 1}} / SetWindowLongPtr),然后从GetWindowLongPtrLPVOID的演员阵容会有意义。但我怀疑这是你在做什么。 (如果你是,那么你不需要string *reinterpret_cast的全部意义在于它没有被解释,所以没有什么可以重新解释。只需使用void *。)< / p>

***或者,最糟糕的是,它似乎可行,但随后导致难以追踪的崩溃或腐败。一些标准C ++库使用特殊的分配器将标头放在字符前面并返回指向第一个字符的指针,这样static_cast可以在string的任何地方使用。在char *类中,每个方法都必须向后捏造string指针;例如,不要只是说this,而是要做m_length之类的事情。但另一种方法是不起作用 - 如果你只有一堆字符,而不是static_cast<_string_header *>(this)[-1]->m_length对象,那么软糖会读取在字符之前分配的任何字节,并尝试将它们解释为一个整数,所以你可能最终认为你有一个长度为0的字符串,或182423742341241243。

答案 1 :(得分:1)

至少有两种方式:

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

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