我正在使用一種API,它在內存中提供了感興趣的字符串的內存地址和長度。我想將這些字符串讀入像wstring這樣的更友好的對象。將memcpy轉換爲向量<wchar_t>來自原始內存位置
對於較小的字符串,靜態大小的緩衝區工作正常使用下面的代碼:
// This code works (but may have other issues)
// _stringLengthOffset and _bufferOffset are provided earlier by the API
// stringOID is the memory location of the string (and in terms of the API, the ObjectID)
DWORD stringLength;
memcpy(&stringLength, ((const void *)(stringOID + _stringLengthOffset)), sizeof(DWORD));
wchar_t argString[DEFAULT_ARGVALUE_BUFFER_SIZE];
memcpy(argString, ((const void *)(stringOID + _bufferOffset)), (stringLength) * sizeof(wchar_t));
argString[stringLength] = L'\0'; // Strings are not null terminated in memory
wstring argumentValue = argString;
我不認爲這是建立一個非常,非常大的靜態大小的緩衝區是一個好主意(這些字符串可能有20000個或更多字符。)我嘗試了幾種不同的方法,並且這段代碼似乎很接近但不起作用。
// This code does NOT work.
vector<wchar_t> buffer;
buffer.reserve(stringLength + 1);
memcpy(&buffer[0], (const void *)(stringOID + _bufferOffset), (stringLength) * sizeof(wchar_t));
buffer.push_back(L'\0');
buffer.shrink_to_fit();
wstring argumentValue(buffer.begin(), buffer.end());
問題:如果我們的目標是創造一個wstring的,如何正確地一個從原始內存(由這個特定的API提供)複製到一個動態大小的緩衝區,然後創建一個wstring的? (道歉,如果這已經回答過了,因爲它看起來像是有人在我之前就問,但我無法找到一個合適的問題/答案與搜索了幾個小時。)
謝謝!這工作。順便說一句,memcpy對靜態大小的緩衝區有多大好處,而不是總是使用「wstring s(pstr,stringLength);」?我猜測現代編譯器沒有,因爲我們最終會使用一個wstring。 – 2013-03-06 00:25:00
本質上,wstring構造將採取數據的副本,以便複製到中間數組是浪費精力。 根據std :: basic_string的實現(即,如果它在內部使用memcpy來處理POD字符類型),直接將memcpy直接寫入未初始化的內存中可能比使用wchar_t *構造字符串更快。 memcpy往往被高度優化(例如,使用SIMD指令或塊移動指令)。另外,你需要支付在堆中分配wstring的內部緩衝區,這比堆棧分配慢。 – Pete 2013-03-06 09:26:53
除非此代碼對性能至關重要,否則我不會擔心。如果優化,通常只有一小部分程序對總體性能有任何影響。 – Pete 2013-03-06 09:28:36