ウィンドウの位置を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が通りません。
この辺はマイクロソフトの不備で、細工せず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用意が無難と言えるでしょう。
もちろん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用意が無難と言えるでしょう。
コメントする