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

reserve はベクトル x wchar_t を長くしません。事前に割り当てるだけです。ベクターは、内部に0個のアイテムがあるとまだ考えています。push_back を呼び出すと、ベクターには 1 文字が含まれるようになりました。Shrink_to_fit は 1 文字のままにします。memcpy は、コピー後どれくらいの時間がかかるかをベクトルに伝えることができません。上記の回答を使用することをお勧めしますが、ベクトルの使用に夢中になっている場合は、予約ではなくサイズ変更です。+1をしないでください。これは push_back で処理されます。

于 2013-03-05T20:31:53.360 に答える