« [Metro] GridView のスクロール開始位置と、スクロール位置の指定 | トップページ | [Metro] 今月のカレンダーを Windows ストア アプリで表示する »

2012年12月 8日 (土)

Windows Phone 8 で Shift-JIS を読む

Windows Phone は 8 が出てから触り始めたという新参者なので、 PCL の話をしてお茶を濁しちゃえ、 と思ってました。
ところが、 月曜日にこんなのを見つけちゃったんですねぇ f(^^;

てことで、 Shift-JIS をエンコードする話をするです♪

● Shift-JIS の困ったちゃん (--;
WP7.x では、 みなさん苦労してきました。 JpEncoding っていうライブラリが使いやすそうなんだけど、 どうも変換テーブルが不完全なのかチラホラと文字化けします。
このへんの話は、 酢酸先生が詳しく書かれてます。 ⇒ Windows PhoneでShift-JISやEUC-JPの文字列を扱う - 酢ろぐ

● Windows Phone Runtime は Windows Runtime のサブセット (^^)
…って話を聞いたときは、 Encoding クラスが Shift-JIS もサポートしてくれると信じていました。
んが、 蓋を開けてみれば、 入っていなかったという… orz

● えっ!? Win32 API の MultiByteToWideChar が使える?
そんなときに見つけたのが、 さきほどのツィートで紹介してる MSDN のページ。
Windows Phone 8 では、 Win32 API の MultiByteToWideChar が使えることになってます。 これは試してみるっきゃないでしょ~w

● 小手調べ: まずは Windows ストア アプリで
DllImport して、 ちょちょいとこんな C# のコードを書いてやれば…

はい、 Shift-JIS で書かれたファイルがちゃんと読めます♪

84

※ ちなみに、 WACK には怒られませんでした。 ストアに出すアプリで MultiByteToWideChar を使ってもよさそうです。 Encoding のサポートがあるので、 使う意味は無いけどw

● WP8 に移植
…いきなり挫折しました orz
上のコードを WP8 のプロジェクトに入れると、 コンパイルは通るんだけど、 実行時に例外っす (;;
MultiByteToWideChar() を呼び出すところで 「System.NotSupportedException: DllImport cannot be used on user-defined methods.」 って怒られた orz

● Windows Phone ランタイム コンポーネント
ぐぐってみると (ってゆーか //Build 2012 の資料を読み漁ってみると)、 どうやら、 Win32 API を呼ぶのは「Windows Phone ランタイム コンポーネント」の中からじゃないとダメっぽい。
Windows ストアアプリの「Windows ランタイム コンポーネント」は .winmd だけど、 「Windows Phone ランタイム コンポーネント」は .dll になるみたい。 (←つまり、同じような「ランタイム コンポーネント」だけど、 互換性は無いということorz )

で、 さらに、 Win32 API を使いたけりゃ C++ で作れ、 とな! orz
いや、 あれってば、 C+++ くらいに異質な言語に化けちゃってるから、 使いたくないのよ~w

● WP8 で MultiByteToWideChar を使う!
やれやれ、 やっとゴールです♪
こんなコードで Windows Phone ランタイム コンポーネントを C+++ で作って…

WP8 の C# からは、 こんなコードで…

…はい、 完成~♪

35

● 人柱ぼしゅーw
てことで、 WP8 では MultiByteToWideChar を呼べるし、 エミュではコードページ 932 も実装されていることが判明しました。 実機を持ってる人は、 ぜひ人柱になってくだされ♪

ソースコードはこちら ⇒ Windows Phone Samples: Windows Phone 8 で Shift-JIS を読む (Win32 API の MultiByteToWideChar を使う)
VS 2012 Express for Windows Phone でコンパイルできます。

● 参考ページ

● 最後に

コードページ932の実装はあるんだから、 Apollo+ では Encoding クラスでもちゃんとサポートしてくださいね♪ > MS
今のままでは、 Web からダウンロードするところやファイルの中身を読み出すところをPCL に書けないので、 すごくやりにくいのですよ。


(2012/12/12 追記)
すみません、 C++/CX のコードがバグってました (修正済み)。 m(_`_)m
いやぁ、 C++/CX だと普通は delete なんて書くことないから… お恥ずかしい! (汗;

指摘してくださった ‏@you_and_i さん、 ありがとうございます♪

@biac Platform::Stringに渡している new した buffUtf16 が解放されていない気がするのは気のせいでしょうか?w http://msdn.microsoft.com/en-us/library/windows/apps/hh6998... サンプルでもPlatform::Stringに渡している文字列のメモリ管理はC++でやってる

posted at 17:10:36

@you_and_i あー、たぶん気のせいじゃないっす(汗;

posted at 17:56:06

@biac ダメ。ゼッタイ。同じAPIでやらかした事がありますw

posted at 18:16:43

.@you_and_i さてデバッグするだ(汗; 1294715回呼び出したところでOutOfMemory例外発生した。再現可能になったので、直すぞ~ f(^^;

posted at 20:09:55

.@you_and_i ぉし、10,000,000回の呼び出しに平気になった(さっきは1,294,715回でメモリ不足例外)。ので、たぶん直った。最後にもう2桁増やして回してみるべ。何分掛かることやらw  (エミュのメモリ残量の見かた、誰か教えて~f(^^; )

posted at 20:22:52

.@you_and_i 風呂入ってる間にテストラン終わってたf(^^; さっきは1分くらいの感じだったから、2桁増やしたら2時間位だろうと思ってたが、やっぱりそんなもんだった。  てことで、1,000,000,000回呼びだして問題無さげだったので、デバッグ終了(^^;

posted at 22:41:36

マルチスレッドじゃないユニットのテストって、昔と違って平気でブン回せるのが、なにげに嬉しいなぁ。ウェイト無しで延々とループさせるテストなんて、1コアの時代はその間PCが使えないも同然の状態になっちゃうから、すごく嫌だったんだ。いまや、CPUを10%も喰わないw

posted at 22:45:39

|

« [Metro] GridView のスクロール開始位置と、スクロール位置の指定 | トップページ | [Metro] 今月のカレンダーを Windows ストア アプリで表示する »

プログラミング」カテゴリの記事

* プログラミング ( Metro スタイル )」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: Windows Phone 8 で Shift-JIS を読む:

« [Metro] GridView のスクロール開始位置と、スクロール位置の指定 | トップページ | [Metro] 今月のカレンダーを Windows ストア アプリで表示する »