簡體   English   中英

從LPVOID檢索字符串

[英]retrieving string from LPVOID

有人可以在這里解釋和幫助我嗎? 可以說我有這樣的功能,其中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);

我正在努力。

這有效,但最后我得到奇怪的字符

這意味着您的字符串不是以Null結尾的,也就是說,它沒有NUL字節( 0 )來標記字符串的結尾。

C字符串必須以空值結尾 。*當您記錄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 (aka void * ,又稱指針指向任何東西)轉換為LPVOID * (aka void ** ,又稱指針指向任何東西的指針)然后再轉換為char * (指針到字符)是錯誤的(並且應該在第二次轉換中向您發出編譯器警告;如果您收到警告而忽略了它們,請不要這樣做!)。 而且,通常最好使用現代強制轉換而不是C樣式強制轉換,並且在沒有缺點的情況下最好使用const正確; 它只是使事情對讀者而言更加明確,並在將來進行維護時更加安全。

最后:

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

幾乎可以肯定這是錯誤的。** LPVOID只是指向一堆字符。 您說的是要將這些字符解釋為好像是string對象。 但是string對象是一些標頭信息(可能是長度和容量等)以及指向一串字符的指針。 將其中一個當作另一個會導致垃圾或崩潰。***


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

**如果實際上有一個string對象,並且該string對象一直存在於某個地方,並且將指向該對象的指針保存在LPVOID ,並且現在已經對其進行了檢索(例如,使用SetWindowLongPtr / GetWindowLongPtr ),則將其從LPVOIDstring *會很有意義。 但是我懷疑那是你在做什么。 (如果是,則不需要reinterpret_cast void *的全部要點是它沒有被解釋,因此沒有什么可以從其重新解釋的。只需使用static_cast 。)

***或者,最糟糕的是,它似乎可以工作,但隨后導致難以跟蹤的崩潰或損壞。 一些標准的C ++庫使用特殊的分配器將標頭放在字符之前,並返回指向第一個字符的指針,以便可以在char *可以使用的任何地方使用string string類內部,每個方法都必須使this指針向后移動。 例如, m_lengthstatic_cast<_string_header *>(this)[-1]->m_length 但是另一種方法不起作用-如果您只有一堆字符,而不是string對象,該軟糖將讀取恰好在字符之前分配的所有字節,然后嘗試將它們解釋為整數,因此您可能最終以為您的字符串長度為0或182423742341241243。

至少有兩種方法:

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

要么

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM