Skip to content

開発日記 vol.12

masami-sugao edited this page Aug 7, 2018 · 7 revisions

ライブラリ用の言語対応

音声ファイルを識別するキーをTCHARにしてたので、利用側とのインターフェースはTCHARを引数に取るものがいっぱい。
これをそれぞれchar版とwchar_t版作るのは大変なので、テンプレートクラスにすることにした。
テンプレートの書き方がよくわからなくて何度も書いては消し…を繰り返したけど、なんとか動くようになりました。

テンプレートクラスにする場合は実装を全てヘッダファイルに書くのが基本みたいなんだけど、結構処理長いから読みにくくなりそうなので、明示的インスタンス化を使ってcppに実装を残すようにした。
このやり方だとテンプレートの型引数に入る型を事前に決めることになるんだけど、今回はcharwchar_tのみとわかっているので問題なし。

テンプレートの特殊化というのも使ってみた。
C#にはない機能で、これがあると関数内で型で判別して処理を分けなくていいから便利だと思う。

OutputDebugString()の言語対応

実験したところ、プロジェクトの言語設定に関わらずShift_JISで出力されていることがわかった。
OutputDebugString()はプロジェクトの言語設定によりOutputDebugStringW()OutputDebugStringA()に置換される。
ライブラリ内でのログ出力時に利用側から渡された文字と組み合わせた文章にした方がわかりやすい場合があり、その場合にライブラリ内で生成した文字列と利用側から渡された文字列の両方の型が可変だとパターンが増えて処理が複雑になる。
これを避けるために、ライブラリ内で生成する文字列はTCHARにはせず常にcharにすることにした。

ログ出力関数変更

ログ出力関数をマクロ関数で書いていたので、C++のメソッドに変更。
C++11から可変長引数を持つ関数のC++専用文法ができたみたい。

wchar_tcharに変換する関数作成

変換後のサイズがわからないので関数呼び出し側で配列を用意するのは難しく、関数内でnewしたものを返却し、呼び出し側で使い終わってからdeleteする形になった。
ライブラリ内部でしか使わないからメモリ解放漏れの危険性はそこまで考えなくていいけど、美しくない。
もっとよいやり方あるのだろうか。