Windows7 と XP で ExpandEnvironmentStrings の挙動が違うもよう。
基本的に XP での動作が怪しい感じ。
ExpandEnvironmentStrings についてはこんな感じ。
DWORD ExpandEnvironmentStrings(
LPCTSTR lpSrc, // 環境変数を表す文字列へのポインタ
LPTSTR lpDst, // 展開後の環境変数を表す文字列へのポインタ
DWORD nSize // 展開後の文字列の最大文字数
);
戻り値
関数が成功すると、展開後の文字列を受け取るバッファに格納された文字数が返ります。
指定したバッファのサイズより展開後の文字列数の方が大きいときは、展開後の文字列を
保持するために必要なバッファのサイズが返ります。
日本語を含む文字列の展開
char* hoge() { DWORD len = ExpandEnvironmentStringsA( "%USERPROFILE%\\デスクトップ", NULL, 0 ); char* str = new char [len]; ExpandEnvironmentStringsA( "%USERPROFILE%\\デスクトップ", str, len ); return str; }
2回目の ExpandEnvironmentStringsA 動的確保したバッファに読み込みます。
使い方に関して、一見問題なさそうですが、
Windows XP では、len に想定外の値が返ってきます。
実際に必要な文字数より大きい値であれば、必要な文字列が取得できるのですが(余分なメモリは確保されてしまうが)小さい値になる場合もあるようで、この場合文字列が切り捨てられてしまいます。
対策としては、余分にバッファを確保するか、ExpandEnvironmentStringsW を使うといったところでしょうか…
非常に長い文字列の展開
日本語を含む文字列の展開については、ExpandEnvironmentStringsW を使うことにして対処しました。しかし、ExpandEnvironmentStringsW にも問題がありました。
TEST(EnvironmentStrings, LongLongString) { wchar_t str[0x10000]; // 適当な文字列を作る for( int i=0; i < 0x10000; ++i ) { str[i] = L'0' + i%10; } str[0x10000-1] = L'\0'; DWORD len = ExpandEnvironmentStringsW( str, NULL, 0 ); ASSERT_EQ( 0x10000, len ); }
追記
- 2012/01/22
TEST(EnvironmentStrings, LongLongString) のコードに間違いがあったので修正しました。
0 件のコメント:
コメントを投稿