ドナドナされるプログラマのメモ

Windows用アプリのプログラミングメモ

mozjpegをつかった画像変換ソフトの開発 その7

mozjpegを使った画像変換ソフト、開発が一段落した。

以下に121個のpngファイルを処理した場合の例を示す。64bit版では約6秒で全ファイルの処理が終わった。


MozJpegGUI 64bit ver. example

なお、32bit版と64bit版を作ったが処理速度は以下のように64bit版のほうが8%ほど早いようだ。メモリ制約も64bit版のほうが少なく、特に理由がない限り64bit版を使うべきだろう。

計433MBのpngファイル911個を処理するのにかかった時間

x86: 115.9 sec.
x64: 106.7 sec.

_RPTN, _RPTWN等をTCHARに対応させる

Visual Studioの出力ウィンドウに文字を出力する_RPT系関数は便利だが、なぜかTCHAR版が無い。

(_RPT系関数の参考)

donadona.hatenablog.jp

仕方ないので、TCHAR版を作ってみた。なお、毎回_CRT_WARNを書くのが面倒だったので入力不要としている。別のものを指定したい場合は、適宜書き換えてください。

TCHAR version of _RPTN functions

これで少し楽ができるようになるはず。

2020/2/23更新:Releaseにて無効化されないミス(ビルドエラー発生)を修正。

CMultiLockの問題

Semaphoreの参照カウント数を知るために、カウント数を保持するクラスを作ってみたのだがうまくカウントしてくれない。原因を調べるために、CMultiLockのコードを読んでみたらびっくりした。Unlock()とかはCSyncObjectクラスのUnlock()を呼び出すようになっているのに。Lock()は直接Win32APIを叩きに行っていて、CSyncObjectのLock()を呼んでいない。そのため、CSemaphoreのLock()をオーバーライドしても意味がない!!!

ちなみにCSingleLockならLock()はちゃんとCSyncObjectのLock()を呼び出しているので安心。

それにしても、どうしてくれよう、この実装・・・。CMultiLockを継承したクラスを作るしかないのか?面倒だなあ。

CEventとCMultiLock::IsLocked

CEventとCMultiLock::IsLocked()の組み合わせでちょっと悩んだのでメモ。

CSemaphoreオブジェクトAのLock待ち中にAbortできるよう、以下のように組んだ。

悩んだのは、IsLocked()。Microsoftのドキュメントでは"Nonzero if the specified object is locked; otherwise 0." (ロックされている場合は非ゼロ, それ以外はゼロ)を返すと書かれている。ところで、CSignalの場合、SetとResetのどちらがロック状態なのだろう?

Reset状態ではLock()を通過できないのでResetがロック状態だと思ったのだが、テストしてみたらSetがロック状態だった。そのため、AbortがSetされたかどうかを確認するのは、if(IsLocked(0) != FALSE){Abort処理} が正解ぽい。

Aborting by using CEvent and CMultiLock

Visual Studioのコード上で32bit用コードと64bit用コードを切り替える

Visual StudioにてC / C++のプログラミングをする際に、32bit向けと64bit向けでコードを変えたくなる場合がある。切り替え自体は当然#ifdefでやるのだが、どの定数で判定するのが良いのだろうか?以下、整理してみた。情報ソースはマイクロソフトの以下記事。

docs.microsoft.com

  • _WIN32
    x86, x64, 32bitARM, 64bitARMのときに1。64bitでも1な点に注意。Windows環境のときのみ何かしたい場合に有用?
  • _WIN64
    x64, 64bitARMのときに1。Windows環境かつ64bit環境のときのみ何かしたい場合に有用。
  • _M_IX86
    x86のときに600。x86のときのみ何かしたい場合に有用。ARM他は別途判定が必要。
  • _M_X64
    x64のときに100。x64のときのみ何かしたい場合に有用。ARM他は別途判定が必要。
  • _M_ARM, _M_ARM64, _M_ARM_ARMV7VE, M_AMD64
    名前から察してください。なおAMD64AMD専用プログラムにする場合のみ指定?Intel/AMD両方用なら_M_X64を指定するのが正しそう。

 

Visual Studioでクラスが登録されていませんというエラーが出る

Visual Studioのリソースエディタで、ダイアログのクラスを追加しようとして「クラスの追加」を選び必要事項を入力したら、「クラスが登録されていません」というエラーがでてしまった。

f:id:donadonasan:20200209124757p:plain

クラスが登録されていません

直接の原因はわからないが、適切なプロジェクトをスタートアッププロジェクトに設定したら治った。ちなみに、英語環境だと以下のエラーになる。

f:id:donadonasan:20200209125148p:plain

Error HRESULT E_FAIL has been returned from a call to COM component