-
Notifications
You must be signed in to change notification settings - Fork 1
開発日記 vol.12
音声ファイルを識別するキーをTCHAR
にしてたので、利用側とのインターフェースはTCHAR
を引数に取るものがいっぱい。
これをそれぞれchar
版とwchar_t
版作るのは大変なので、テンプレートクラスにすることにした。
テンプレートの書き方がよくわからなくて何度も書いては消し…を繰り返したけど、なんとか動くようになりました。
テンプレートクラスにする場合は実装を全てヘッダファイルに書くのが基本みたいなんだけど、結構処理長いから読みにくくなりそうなので、明示的インスタンス化を使ってcppに実装を残すようにした。
このやり方だとテンプレートの型引数に入る型を事前に決めることになるんだけど、今回はchar
かwchar_t
のみとわかっているので問題なし。
テンプレートの特殊化というのも使ってみた。
C#にはない機能で、これがあると関数内で型で判別して処理を分けなくていいから便利だと思う。
実験したところ、プロジェクトの言語設定に関わらずShift_JISで出力されていることがわかった。
OutputDebugString()
はプロジェクトの言語設定によりOutputDebugStringW()
かOutputDebugStringA()
に置換される。
ライブラリ内でのログ出力時に利用側から渡された文字と組み合わせた文章にした方がわかりやすい場合があり、その場合にライブラリ内で生成した文字列と利用側から渡された文字列の両方の型が可変だとパターンが増えて処理が複雑になる。
これを避けるために、ライブラリ内で生成する文字列はTCHAR
にはせず常にchar
にすることにした。
ログ出力関数をマクロ関数で書いていたので、C++のメソッドに変更。
C++11から可変長引数を持つ関数のC++専用文法ができたみたい。
変換後のサイズがわからないので関数呼び出し側で配列を用意するのは難しく、関数内でnewしたものを返却し、呼び出し側で使い終わってからdeleteする形になった。
ライブラリ内部でしか使わないからメモリ解放漏れの危険性はそこまで考えなくていいけど、美しくない。
もっとよいやり方あるのだろうか。