Visual C++でvsscanf

| コメント(0) | トラックバック(0)
ウィンドウの位置を1エントリで自然に記録しようと"%d %d %d %d"で書き込んだら、読み出す時に困りました。
もちろんsscanf系で取れるのですが、ワンクッション挟むにはvsscanf系が必要で、これがVisual C++にはありません。

有名どころでは、Cライブラリの内部関数_input_l及び_winput_lを使う方法がありますが、内部関数なので静的リンク必須ですし、互換性は保証されません。

簡易実装する方法はいくらでもあります。数値以外がなく区切り文字が決まっているなら、strtokで切り出しながらsscanfに渡す手があるでしょう。

でももっともっと汎用的に、と調べていたら、面白いものを発見しました。
flipcode - vsscanf for Win32

va_listの中身は大抵の実装では引数(格納する変数へのポインタ)の配列なので、sscanf用に並べ直せばいいじゃないか、というものです。引数の生成はスタックの操作ですから、インラインアセンブラが使われています。

これも有用だったのですが、x64非対応です。x64ではインラインアセンブラ自体が使えなくなっていますし、呼び出し規則も違います。

というわけで、アセンブラ部をasmファイルに分け、x86/x64両対応にしてみました。
vsscanf.zip

同梱プロジェクはVisual Studio 2008用で、カスタムビルド規則として"Microsoft Macro Assembler"を有効にしてありますが、このままではx64が通りません。
Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\x86_amd64
にあるml64.exeをml.exeにコピーする必要があります。

この辺はマイクロソフトの不備で、細工せずml64.exeを呼び出す方法がないのです。x86_amd64\ml.exeを用意するか、x64用カスタムビルド規則を作成するかしかありません。

flipcodeも私の移植版も、有効な%を数えてはva_listから取り出すので、%の方が多ければsscanf同様に即死するのでご注意。

(2013/02/06追記)
Visual Studio 2010だとml.exeとml64.exeを自動で切り替える仕組みが入っていました。
やはり追加カスタムビルド規則は2010以降への変換後が面倒になるので、x86_amd64\ml.exe用意が無難と言えるでしょう。

トラックバック(0)

トラックバックURL: http://mychro.mydns.jp/cgi-bin/mt/mt-tb.cgi/347

コメントする

アーカイブ

ウェブページ

Powered by Movable Type 5.2.13

ホームページ