简体   繁体   English

记忆载体 <wchar_t> 从原始内存位置

[英]memcpy into a vector<wchar_t> from raw memory location

I'm working with an API that provides, in memory, the memory address and length of strings of interest. 我正在使用一个API,该API在内存中提供内存地址和感兴趣的字符串的长度。 I'd like to read these strings into friendlier objects like wstring. 我想将这些字符串读入更友好的对象,例如wstring。

For smaller strings, a statically sized buffer works fine using the following code: 对于较小的字符串,使用以下代码可以很好地使用静态大小的缓冲区:

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



I don't think it is a good idea to create a very, very large statically sized buffer (20,000 characters or more are possible with these strings.) I've tried several different approaches and this code seems close but does NOT work. 我认为创建一个非常大的静态大小的缓冲区(这些字符串可以容纳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() );

Question: If the goal is creating a wstring, how does one correctly copy from raw memory (as provided by this particular API) into a dynamically sized buffer and then create a wstring? 问题:如果目标是创建wstring,那么如何将原始内存(由该特定API提供)正确地复制到动态大小的缓冲区中,然后创建wstring? ( Apologies if this has been answered before, as it seems like something someone before me would have asked but I was unable to find an appropriate question/answer with a few hours of searching. ) (很抱歉,如果以前已经回答过这个问题,因为似乎有人在问我,但经过几个小时的搜索却找不到合适的问题。

There's a number of ways. 有很多方法。

1) Use resize instead of reserve and do the memcpy. 1)使用调整大小而不是保留大小并执行memcpy。 also get rid of the shrink fit. 也摆脱了收缩契合。

2) Assign directly to the string: 2)直接分配给字符串:

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

option 2) avoids a copy and additionally initialization of the resized vector. 选项2)避免了复制,也避免了大小调整后的向量的初始化。

std::wstring foo (somebuffer, charactercount);

reserve doesn't make a vector x wchar_t's long. 储备不能使向量x wchar_t长。 it just preallocates. 它只是预分配。 the vector still thinks it has 0 items inside. 向量仍然认为里面有0个项目。 when you call push_back the vector now contains 1 character. 当您调用push_back时,向量现在包含1个字符。 shrink_to_fit will leave it at 1 character. rinkle_to_fit将其保留为1个字符。 memcpy is unable to tell the vector how long it will be after the copy. memcpy无法告诉向量复制后将要经过多长时间。 I'd recommend using the answer above but if you're hell bent on using a vector, it's resize, not reserve. 我建议使用上面的答案,但是如果您不愿意使用向量,则它会调整大小,而不是保留。 and don't do the +1. 并且不要执行+1。 That will be handled in the push_back. 这将在push_back中处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM