「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
nullptr
記事: 239
登録日時: 8年前

「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

#1

投稿記事 by nullptr » 7年前

「(☝՞ ਊ ՞)☝イェェェェェwwwwwウッヒョオオwwww✌✌✌✌✌✌( 'ω')✌✌✌✌✌✌ _| ̄| Σ・∴'、-=≡( ՞ਊ ՞)ドコドコドコwwww」
この文字列を、VisualStudioデバッグ出力ウィンドウに表示すると、
「(?? ? ?)?イェェェェェwwwwwウッヒョオオwwww??????( 'ω')?????? _| ̄| Σ・∴'、-=≡( ???)ドコドコドコwwww」
となります。コンソールも当然表示されません。
これをせめてデバッグ出力に正常に表示することはできますでしょうか?

プロジェクトの文字コードはUnicodeにし、OutputDebugStringWで吐き出す場合です。


一応補足すると、
メールを自前で管理したい
→(BASE64エンコードされた)UTF-8のメールがある(この文字列がある)
→UTF8じゃ扱いにくいからWindows向けにUTF16LEに変換したい
→グリグリして変換、結果を確認したい
→コンソールはもちろんデバッグウィンドウに表示できない

といった流れです。
正直文字列があほらしいのですが、知人が実際にこういうメールも送ってくるので仕方ありません。
面倒なんですがバイナリで吐き出して正常に変換できていることは確認しました(そのため文字コードが間違っていることはないはず)。やはりデバッグ出力なりで確認する方が楽なので、もし方法があればご教授願いたいと思い質問させて頂きました。

あくまでも願望に近いので、無ければ無いで構わないのですが。

---環境--
・Microsoft Visual Studio Professional 2012
・C++
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

YuO
記事: 941
登録日時: 9年前
住所: 東京都世田谷区

Re: 「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

#2

投稿記事 by YuO » 7年前

設定上なさそうですね。

C#では表示できるので,

コード:

using System.Diagnostics;

class Program
{
    static void Main (string[] args)
    {
        Debug.WriteLine("C# : \u3041\u2600");
    }
}

コード:

#include <Windows.h>

int main (void)
{
    OutputDebugStringW(L"Cpp : \u3041\u2600\r\n");
}
というソースをもつソリューション(ソリューション自体はC#側で作成)をマルチスタートアップで実行すると,

コード:

Cpp : ぁ?
C# : ぁ☀
と出てきました。
参照用ソースを辿ると,Debugger.Logメソッドを使っているところまではわかりました (Debugger.IsLogging()でなければOutputDebugStringを使うようですが,実際にはTrueなので) が,
Debugger.Log はexternなメソッドなので,そこからは追うことが出来ませんでした。
externといってもP/Invoke宣言ではなく,

コード:

        // Posts a message for the attached debugger.  If there is no
        // debugger attached, has no effect.  The debugger may or may not
        // report the message depending on its settings. 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)] 
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        public static extern void Log(int level, String category, String message);
というものです。


OutputDebugStringWですが,元々OutputDebugString function (Windows)
OutputDebugStringW converts the specified string based on the current system locale information and passes it to OutputDebugStringA to be displayed. As a result, some Unicode characters may not be displayed correctly.
とあり,OutputDebugStringAで出力されていて,さらに
OutputDebugStringW cannot correctly handle UNICODE characters | Microsoft Connectによると,Unicodeを出力できるようには修正しない,というような状況のようです。

既存の外部のデバッガがAで作られているためにWで出力できなかった,という互換性のための仕様変更不可能,という可能性もありそうな気がします。


デバッグ時のみ/clrでコンパイルしてSystem::Diagnostics::Debug::Writeを使えば通りそうですが,そこまでするか,という気もしますし……。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: 「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

#3

投稿記事 by softya(ソフト屋) » 7年前

ざっと知らべてみましたが出来ませんね。
勘での発言ですが、ライブラリレベルでマルチバイト文字の処理とかが何処かに残っていて害を及ぼしている様な印象を持ちました。
あくまで勘ですので詳細はわかりません。
少なくともexeファイルにはちゃんとしたUTF-16LEの文字コードで格納されています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
nullptr
記事: 239
登録日時: 8年前

Re: 「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

#4

投稿記事 by nullptr » 7年前

>YuO様
YuO さんが書きました:設定上なさそうですね。

OutputDebugStringWですが,元々OutputDebugString function (Windows)
OutputDebugStringW converts the specified string based on the current system locale information and passes it to OutputDebugStringA to be displayed. As a result, some Unicode characters may not be displayed correctly.
とあり,OutputDebugStringAで出力されていて,さらに
OutputDebugStringW cannot correctly handle UNICODE characters | Microsoft Connectによると,Unicodeを出力できるようには修正しない,というような状況のようです。

既存の外部のデバッガがAで作られているためにWで出力できなかった,という互換性のための仕様変更不可能,という可能性もありそうな気がします。


デバッグ時のみ/clrでコンパイルしてSystem::Diagnostics::Debug::Writeを使えば通りそうですが,そこまでするか,という気もしますし……。
詳しい解説有難う御座います。私も、C#で吐き出せるのを知っていたので、やり方次第でC++でも吐き出せるかもしれないと思いましたが、無理でしたか。英語の資料は読み違うことが多い・・・。
C++はCへの互換もせねばならないし、Unicodeはやはりまだ扱いにくいのですね。C++11で少しはマシになった気がしますが、MVC++はとてつもなく対応してないですし。

softya(ソフト屋) さんが書きました:ざっと知らべてみましたが出来ませんね。
勘での発言ですが、ライブラリレベルでマルチバイト文字の処理とかが何処かに残っていて害を及ぼしている様な印象を持ちました。
あくまで勘ですので詳細はわかりません。
少なくともexeファイルにはちゃんとしたUTF-16LEの文字コードで格納されています。
やはりですか・・・。
私もバイナリをおったのでUTF-16LEの文字コードで格納されていることは確認したのですが、デバッガ等に吐き出せると良かったんですけどね。この後UTF16LEをUTF32やShift_JISやJISなどに相互変換するコードを書いてみるつもりだったので、デバッガで簡単に確認できたら楽だったのですが。




ともあれ現状は難しそうです。他の方法を考えてみます。有難う御座いました。
 
 
✜ で C ご ✜
: す + 注 :
¦ か + 文 ¦
?
Is the は :
order C++? ✜
     糸冬   
  ――――――――
  制作・著作 NHK
 
 

YuO
記事: 941
登録日時: 9年前
住所: 東京都世田谷区

Re: 「(☝՞ ਊ ՞)☝」などの文字をデバッグ出力に表示する方法

#5

投稿記事 by YuO » 7年前

解決済みで2ヵ月半前の話ですが,ちょっと追試的なことをしたので。
C#側からのアプローチなので,C++側からUnicodeで出力できる,というような話ではありませんのであしからず。

実行環境:Visual Studio 2012 Express for Windows Desktop / C# / .NET Framework 4.5 / Windows 8
必須環境(予想):.NET Framework 3.5かそれ以降の.NET Frameworkと,それに対応したVisual Studio,およびその上で動くC#

コード:

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("Kernel32", CharSet = CharSet.Auto, ExactSpelling = false, SetLastError = true)]
    private static extern void OutputDebugString ([In, Optional, MarshalAs(UnmanagedType.LPTStr)] string lpOutputString);

    [DllImport("Kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
    private static extern void OutputDebugStringA ([In, Optional, MarshalAs(UnmanagedType.LPStr)] string lpOutputString);

    [DllImport("Kernel32", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
    private static extern void OutputDebugStringW ([In, Optional, MarshalAs(UnmanagedType.LPWStr)] string lpOutputString);

    static void Main (string[] args)
    {
        var text = String.Concat(Enumerable.Range(0xA1, 0xFF - 0xA1 + 1).Select(n => (char)n)) + "\r\n";
        Debug.Write(text);
        OutputDebugString(text);
        OutputDebugStringA(text);
        OutputDebugStringW(text);

        text = String.Concat(Enumerable.Range(0x21, 0x7E - 0x21 + 1).Select(n => (char)n)) + "\r\n";
        Debug.Write(text);
        OutputDebugString(text);
        OutputDebugStringA(text);
        OutputDebugStringW(text);

        return;
    }
}
に対して,出力は,「ネイティブ コード デバッグを有効にする」がOFFでは

コード:

¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
で,ONでは

コード:

!¢£?\|§¨ca≪¬-R ̄°±23´μ¶・,1o≫????AAAAAAACEEEEIIIIDNOOOOO×OUUUUYTsaaaaaaaceeeeiiiidnooooo÷ouuuuyty
!¢£?\|§¨ca≪¬-R ̄°±23´μ¶・,1o≫????AAAAAAACEEEEIIIIDNOOOOO×OUUUUYTsaaaaaaaceeeeiiiidnooooo÷ouuuuyty
!¢£?\|§¨ca≪¬-R ̄°±23´μ¶・,1o≫????AAAAAAACEEEEIIIIDNOOOOO×OUUUUYTsaaaaaaaceeeeiiiidnooooo÷ouuuuyty
!¢£?\|§¨ca≪¬-R ̄°±23´μ¶・,1o≫????AAAAAAACEEEEIIIIDNOOOOO×OUUUUYTsaaaaaaaceeeeiiiidnooooo÷ouuuuyty
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
でした。
ネイティブコードデバッグ無効ではOutptuDebugStringをすべて無視し,有効ではすべてA扱いで処理しています(おそらく,OutputDebugString出力)。
ここから,.NETのDebug.Write,というかDebug.LogはVS下ではOutputDebugStringではない方法でVSと通信しているようです。
実際,Windows Debugging (Windows Debuggers)には,
Visual Studio includes its own debugging environment and debugging engine, which together are called the Visual Studio debugger. The Visual Studio debugger is completely different from Windows debugger.
などと書かれています。
……どんどん無理じゃないか,という方向へ突っ走っていますが……。

閉鎖

“C言語何でも質問掲示板” へ戻る