SATOXのシテオク日記

~ふもっふ、ふもふも~

STL文字列とStringの相互変換

すいません、SATOXのシテオク日記では初めてですかね……何って、プログラミングのお話ですぞ(笑)。
.NETで遊び初めてしばらく経ちましたが、腹の立つことがありました。
「System::Stringをcharポインタにする」
いやぁ、きっとコレって過去の資産を活用したいすべての人が避けては通れない道だと思います。皆さんはすんなり解決してるんでしょうか。SATOXは悩みましたよ〜(笑)。



C++マネージ拡張のSystem::Stringって、ANSIのキャラ文字列に簡単に変換出来ないんですね! MFCのCStringなら、次のコードでcharポインタゲットしてたですよ。

char *charptr = str.GetBuffer(str.GetLength());
それが、System::Stringはどう調べてもなっかなかcharポインタに出来ない。
また、実は今回の目的はSystem::StringをSTLのstd::stringにするってなこと。もちろん、SystemがSTLと仲が良いはずもなく、まずはcharポインタにすべしと本能が感じ取ったのでした……。
.NET/WindowsLinuxMacで共通ライブラリで楽しようと思ったらSTLくらいしかないでしょ!?
………で、勿体ぶらずにたどり着いたのが次のソースコード(.NET/CLRじゃないです)。
いや、バカみたいに難しいんですけど、これもマネージ拡張の世界だからデスカ!? 移植性とかに重きを置くと、ただ苦しいだけなんですけども……。

using namespace System::Runtime::InteropServices;
/* System::Stringをstd::stringに変換 */
void StdStringToSystemString(std::string *outstr, String *instr)
{
// Ansi文字領域の取得
IntPtr intptr = Marshal::StringToHGlobalAnsi(instr);
// charポインタ取得
const char *char_ptr = (const char *)(intptr.ToPointer());
// std::stringに変換
*outstr = char_ptr;
// Ansi文字領域の解放
Marshal::FreeHGlobal(System::IntPtr( (void *)char_ptr));

return;
}

ついでに逆の変換も(笑)。

/* std::stringをSystem::Stringに変換 */
void SystemStringToStdString(String *outstr, std::string instr)
{
outstr = new String(instr.c_str());
}
System.Runtime.InteropServices名前空間のヘルパクラスを発掘してこないと変換できないというオチ。別の問題でSystem::Stringに入ったEUC文字コードUTF-8にしたいのですが、道のりは遠そう……。