none
char* からStringを作ると文字化けする RRS feed

  • 質問

  • CIL自体はは今日触ったばかりの初心者です。でもCの基本構文とC#で.netについては理解してるつもりです。

    デバッグ出力用にと、RubyからC/CILでつくったDLLに文字を送信するプログラムを作ってみたのですが、日本語を送ると文字コードがおかしいのか文字化けしてしまいます。。

    具体的な動作としましては、rubyのWin32APIクラスででDLLを読みこんで下のWiriteLine関数を呼び出すと、.netのフォームを作成してフォームの中にあるテキストボックスに引数として送られてきた文字列に改行を加えて表示するという単純なものです。
    ソースです。

    __declspec(dllexport) void __stdcall WiriteLine(char* data)
    {
    	String^ dataM = gcnew String(data);
    	if(Global::out_form == nullptr)
    	{
    		Global::out_form = gcnew Out();
    		Global::out_form->Show();
    	}
    	Global::out_form->textBox1->Text += dataM+L"\r\n";
    }
    

    文字化けした文字列と同じ文字列をいろいろな文字コードで保存し、バイナリエディタで表示してみて引数に入ってくる文字列はUTF-8のボムなしで、アプリケーションで表示に使われてる文字コードはShift-JISだと分かりました。
    そこで
    array<Byte>^ enc_data = System::Text::Encoding::GetEncoding(932)->GetBytes(gcnew String(data));
    String^ dataM = System::Text::Encoding::UTF8->GetString(enc_data);
    とか
    array<Byte>^ enc_data = System::Text::Encoding::UTF8->GetBytes(gcnew String(data));
    String^ dataM = System::Text::Encoding::GetEncoding(932)->GetString(enc_data);
    とかいろいろやってみたのですが、いずれにしても同じように文字化けしました。。


    どうすれば文字化けしないで表示できるのでしょうか。教えてください。
    • 編集済み kassyi 2009年9月6日 12:07 コピペミス
    2009年9月6日 12:05

回答

  • デバッグ出力用にと、RubyからC/CILでつくったDLLに文字を送信するプログラムを作ってみたのですが、日本語を送ると文字コードがおかしいのか文字化けしてしまいます。。

    本筋とは関係ありませんが、CIL ではなく、 CLI (Common Language Interface) です。

    String^ dataM = gcnew String(data);

    array<Byte>^ enc_data = System::Text::Encoding::GetEncoding(932)->GetBytes(gcnew String(data));

    1 行目は data を Shift-JIS とみなして、Unicode の String クラスのインスタンスを作るコードです。この時点で無理矢理解釈されたり、他の文字に置き換えられたりするので、文字化けしますし、元の情報を得ることができなくなります。
    2 行目は 同じことをしているので、文字化けした(情報が欠落した) String から Encoding クラスを使っても、どうにもなりません。

    文字化けした文字列と同じ文字列をいろいろな文字コードで保存し、バイナリエディタで表示してみて引数に入ってくる文字列はUTF-8のボムなしで、アプリケーションで表示に使われてる文字コードはShift-JISだと分かりました。

    この時点で、2 つのアプローチが考えられます。
    1 番目は Ruby から Shift-JIS で渡せるようにすること。2 番目は Unicode で受け取るように関数を変更すること。

    2 番目の方法は wchar_t* 等に変えないといけないと思われます。
    軽く検索してみたところ、MessageBoxA を呼び出すサンプルを掲載している方がいましたので、リンクしておきます。

    http://takumakei.blogspot.com/2009/04/require-dl.html

    char* のままいくのであれば MessageBoxA の例を、wchar_t* に切り替えるのであれば MessageBoxW の例を参考にすれば良さそうです。



    # 申し訳ないですが、試していません。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク kassyi 2009年9月6日 14:26
    2009年9月6日 12:52
    モデレータ

すべての返信

  • デバッグ出力用にと、RubyからC/CILでつくったDLLに文字を送信するプログラムを作ってみたのですが、日本語を送ると文字コードがおかしいのか文字化けしてしまいます。。

    本筋とは関係ありませんが、CIL ではなく、 CLI (Common Language Interface) です。

    String^ dataM = gcnew String(data);

    array<Byte>^ enc_data = System::Text::Encoding::GetEncoding(932)->GetBytes(gcnew String(data));

    1 行目は data を Shift-JIS とみなして、Unicode の String クラスのインスタンスを作るコードです。この時点で無理矢理解釈されたり、他の文字に置き換えられたりするので、文字化けしますし、元の情報を得ることができなくなります。
    2 行目は 同じことをしているので、文字化けした(情報が欠落した) String から Encoding クラスを使っても、どうにもなりません。

    文字化けした文字列と同じ文字列をいろいろな文字コードで保存し、バイナリエディタで表示してみて引数に入ってくる文字列はUTF-8のボムなしで、アプリケーションで表示に使われてる文字コードはShift-JISだと分かりました。

    この時点で、2 つのアプローチが考えられます。
    1 番目は Ruby から Shift-JIS で渡せるようにすること。2 番目は Unicode で受け取るように関数を変更すること。

    2 番目の方法は wchar_t* 等に変えないといけないと思われます。
    軽く検索してみたところ、MessageBoxA を呼び出すサンプルを掲載している方がいましたので、リンクしておきます。

    http://takumakei.blogspot.com/2009/04/require-dl.html

    char* のままいくのであれば MessageBoxA の例を、wchar_t* に切り替えるのであれば MessageBoxW の例を参考にすれば良さそうです。



    # 申し訳ないですが、試していません。


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    • 回答としてマーク kassyi 2009年9月6日 14:26
    2009年9月6日 12:52
    モデレータ
  • 回答ありがとうございます!!
    Rubyとはいっても、RGSS2(RPGツクールVX)なのでリンクしていただいたサイトの情報のままは使えませんでしたが、頂いたヒントをもとにググりまくったところ
    RGSS2はNKFが使えるらしくRubyでShif-JIS変換してからDLLに渡すことで無事文字化けせずに日本語を渡すことができました!!

    ありがとうございました!!
    2009年9月6日 14:26