4

我正在使用一个 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 个或更多字符。)我尝试了几种不同的方法,这段代码看起来很接近但不起作用。

// 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?如果之前已经回答过这个问题,我们深表歉意,因为我之前的某个人似乎会问一些问题,但经过几个小时的搜索,我无法找到合适的问题/答案。

4

2 回答 2

4

有很多方法。

1)使用调整大小而不是保留并执行memcpy。也摆脱了收缩配合。

2)直接赋值给字符串:

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

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

于 2013-03-05T20:36:33.567 回答
2
std::wstring foo (somebuffer, charactercount);

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

于 2013-03-05T20:31:53.360 回答