スレッド: [csharpll:0291] <教> System::String → std::string

スレッド

[csharpll:0291] <教> System::String → std::string

[ | ▲ / | ]
Subject:
[csharpll:0291] <教> System::String → std::string
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Wed, 1 Feb 2006 16:26:31 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1506
Message-Id:
<086801c62700$d2ce0c40$e5d2060a@ncosltcff2>
επιστημη@長文御免 です。

にわかにC++/CLIづいてきました^^;

手始めにC++とC++/CLIとのインピーダンス・マッチングを
いろいろと考えてたりするわけで、いっとう最初にくるのが
文字列。System::Stringとstd::string/wstring間を自由に
行き来したいわけ。以前 うぇね さんに教わりました。

#define CODEPAGE 932

// System::String→std::string (Unicode→shift_jis)
std::string Stos(System::String^ clistr) {
 assert( clistr != nullptr );
 // wchat_t列を手に入れ
 array<System::Char>^ warr = clistr->ToCharArray();
 if ( warr->Length ) {
   // ピン留めして
   pin_ptr<System::Char> wptr(&warr[0]);
   // 変換後の長さを調べ
   int len = ::WideCharToMultiByte(CODEPAGE, 0, wptr,
                          clistr->Length, 0, 0, 0, 0);
   if ( len > 0 ) {
     // バッファをこさえて
     std::string result(len+1, '\0');
     // まぢ変換
     ::WideCharToMultiByte(CODEPAGE, 0, wptr,
                  clistr->Length, &result[0], len, 0, 0);
     // 末尾の'\0'を取っ払って
     result.resize(len);
     // できあがり
     return result;
   }
 }
 return std::string();
}

これでいいっちゃいいんですけど、周知の通り VC++2005express
ではWin32APIが(そのままでは)使えない。なので変換部を.NETで
まかないてぇ。そこでごちょごちょやってたのがコレ:

System::String^ unicodeString = L"これはUNICODE,漢字も混じってる";
// Unicodeとshift_jisのencodingを用意し
System::Text::Encoding^ unicode   = System::Text::Encoding::Unicode;
System::Text::Encoding^ shift_jis =
System::Text::Encoding::GetEncoding(932);
// Unicode→バイト列
array<Byte>^ unicode_array = unicode->GetBytes(unicodeString);
// unicodeバイト列→shift_jisバイト列
array<Byte>^ sjis_array =
 System::Text::Encoding::Convert(unicode, shift_jis, unicode_array);
// ピン留めして
pin_ptr<Byte> str(&sjis_array[0]);
// unsigned char列からごりごりとstd::stringへ
std::string result(
 reinterpret_cast<char*>(static_cast<unsigned char*>(str)),
 sjis_array->Length);
// できあがり
std::cout << '[' << result << "]\n";

で、質問つかご相談: 「もちっと簡単にできんもんじゃろか?」

[csharpll:0293] Re: <教> System::String → std::string

[ | / | ]
Subject:
[csharpll:0293] Re: <教> System::String → std::string
From:
宮嶋 隆 <miyajima@...>
Date:
Wed, 01 Feb 2006 16:49:05 +0900
Message-Id:
<43E067F1.9010507‐at‐rd.hzs.co.jp>
In-Reply-To:
291
References:
291
 宮嶋です。

FUKUDA, Fumiki wrote:
>
> 手始めにC++とC++/CLIとのインピーダンス・マッチングを
> いろいろと考えてたりするわけで、いっとう最初にくるのが
> 文字列。System::Stringとstd::string/wstring間を自由に
> 行き来したいわけ。以前 うぇね さんに教わりました。
>

std::string text;  // 文字列を受け止めるバッファ
String^ textString = gcnew String("適当なサンプル文字列");

IntPtr mptr = Marshal::StringToHGlobalAnsi(textString);
text = static_cast<const char*>(mptr.ToPointer());
Marshal::FreeCoTaskMem(mptr);

 えっと、これでどうでしょう?

 それでは、失礼します。

--
日立造船情報システム株式会社
EIT 統括部 技術部

宮嶋 隆
mailto:miyajima@...

[csharpll:0294] Re: <教> System::String → std::string

[ | / | ]
Subject:
[csharpll:0294] Re: <教> System::String → std::string
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Wed, 1 Feb 2006 17:02:04 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1506
Message-Id:
<08a801c62705$cb1b6dd0$e5d2060a@ncosltcff2>
References:
291 293
επιστημηです。速攻でどぉも。

> std::string text;  // 文字列を受け止めるバッファ
> String^ textString = gcnew String("適当なサンプル文字列");
>
> IntPtr mptr = Marshal::StringToHGlobalAnsi(textString);
> text = static_cast<const char*>(mptr.ToPointer());
> Marshal::FreeCoTaskMem(mptr);
>
>  えっと、これでどうでしょう?

あら簡単。これってshift_jisにするですか?
shift_jisにするかgb18030にするかどーのこーのは
Windowsの"国設定"で決まるっちゅーことでしょか?

[csharpll:0295] Re: <教> System::String → std::string

[ | / | ]
Subject:
[csharpll:0295] Re: <教> System::String → std::string
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Wed, 1 Feb 2006 17:32:19 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1506
Message-Id:
<08d701c6270a$06c6b5c0$e5d2060a@ncosltcff2>
References:
291 293 294
επιστημηです。

余談。

> > IntPtr mptr = Marshal::StringToHGlobalAnsi(textString);

using namespace があんまし好きじゃないのでフル修飾してみた:

System::IntPtr mptr =
System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(unicodeString
);

…な、長ぇよ orz
# 僕の画面、しょぼい1034x768です。IDEだと狭いのなんの。

[csharpll:0296] Re: <教> System::String → std::string

[ | / | ]
Subject:
[csharpll:0296] Re: <教> System::String → std::string
From:
宮嶋 隆 <miyajima@...>
Date:
Wed, 01 Feb 2006 17:42:40 +0900
Message-Id:
<43E07480.60903‐at‐rd.hzs.co.jp>
In-Reply-To:
294
References:
291 293 294
 宮嶋です。

FUKUDA, Fumiki wrote:
>> Marshal::FreeCoTaskMem(mptr);

 こいつは Marshal::FreeHGlobal(mptr); でお願いします。
 2.0 からはこっちが正規のようです。

# ドキュメントによって、メモリ開放のメソッドが違うのは
# 勘弁してほしい。

>
> あら簡単。これってshift_jisにするですか?
> shift_jisにするかgb18030にするかどーのこーのは
> Windowsの"国設定"で決まるっちゅーことでしょか?

http://msdn2.microsoft.com/ja-jp/library/system.runtime.interopservices.marshal.stringtohglobalansi.aspx

 これを見ると、ANSI形式とだけ書いてあるので、CP_ACP と同じ
振る舞いをすると見てよいかと思います。ですから、ロケールに
よって変わると思います。

 ではでは。

--
日立造船情報システム株式会社
EIT 統括部 技術部

宮嶋 隆
mailto:miyajima@...

[csharpll:0297] Re: <教> System::String → std::string

[ | / ▼ | ]
Subject:
[csharpll:0297] Re: <教> System::String → std::string
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Thu, 2 Feb 2006 15:25:28 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1506
Message-Id:
<00ce01c627c1$76267100$e5d2060a@ncosltcff2>
References:
291 293 294 296
επιστημηです。

> >> Marshal::FreeCoTaskMem(mptr);
>  こいつは Marshal::FreeHGlobal(mptr); でお願いします。
>  2.0 からはこっちが正規のようです。

いろいろとどぉも。

シャレでこんなのこしらえたなり.

 template<typename Ch, typename Tr =std::char_traits<Ch>,
          typename Al =std::allocator<Ch> >
 struct to_std : std::unary_function<System::String^,
                           std::basic_string<Ch,Tr,Al> > {};

 template<>
 struct to_std<char> : std::unary_function<System::String^,std::string> {
   std::string operator()(System::String^ clistr) const {
     System::IntPtr mptr =
System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(clistr);
     std::string result(static_cast<const char*>(mptr.ToPointer()));
     System::Runtime::InteropServices::Marshal::FreeHGlobal(mptr);
     return result;
   }
 };

 to_std<char> converter; ← おちゃらか変換機
 std::string result = converter(gcnew String(L"雲丹符号"));

Navigation

検索

[検索ヘルプ]

Maintener: Tietew <www.tietew.jp>
Powered by Ruby on Rails, Mongrel, PostgreSQL, and Hyper Estraier.
click here