从原始内存位置</wchar_t>将memcpy转换为vector <wchar_t>

时间:2013-03-05 20:27:19

标签: c++ c++11 stdvector memcpy wstring

我正在使用一个API,它在内存中提供了感兴趣的字符串的内存地址和长度。我想把这些字符串读成更友好的对象,比如wstring。

对于较小的字符串,使用以下代码可以正常大小的缓冲区工作:

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



我不认为创建一个非常非常大的静态缓冲区是个好主意(使用这些字符串可以使用20,000个字符或更多字符。)我尝试了几种不同的方法,这些代码似乎很接近但不起作用。 / p>

// 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?道歉,如果之前已经回答过,因为看起来像我之前会有人问过,但我找不到合适的问题/答案,只需要几个小时的搜索。

2 个答案:

答案 0 :(得分:4)

有很多方法。

1)使用resize而不是reserve并执行memcpy。也摆脱了收缩。

2)直接分配给字符串:

const wchar_t* pstr = reinterpret_cast<const wchar_t*>(stringOID + _bufferOffset);
wstring s(pstr, pstr + stringLength);
// or:
wstring s(pstr, stringLength);

选项2)避免复制并另外初始化调整大小的矢量。

答案 1 :(得分:2)

std::wstring foo (somebuffer, charactercount);

保留不会使向量x wchar_t很长。它只是预先分配。向量仍然认为它里面有0个项目。当你调用push_back时,向量现在包含1个字符。 shrink_to_fit将保留1个字符。 memcpy无法告诉向量复制后它将有多长时间。我建议使用上面的答案,但如果你一直在使用矢量,它会调整大小,而不是保留。并且不要做+1。这将在push_back中处理。