<備忘録> OpenCVのVisual Studioビルドにハマった件

OpenCV 3.0をVisual Studio2013でビルドしたものを使っていたが、Visual Studio2015に環境を変えたいので、VS2015でもビルドした。

無事ビルド完了し実行したのだが、RELEASEビルドが"BEX64 例外コードc0000417"で実行時に落ちる。 DEBUGビルドを実行すると、OpenCVの特徴点Matcherを呼び出した時に得た、マッチング結果の解放時に落ちている。

これはいわゆる、ライブラリとアプリケーションのランタイムの不整合が原因だなと思ってソリューションを見直してみたが、ランタイムはともにマルチスレッドDLLで違い無し。 どうもVS2015から、CランタイムのDLLがユニバーサルCRT(ucrtbase.dll, ucrtbased.dll)に変わったらしく、これが当初バグを含んでいたらしい。(この記事が詳しい)

https://dev.activebasic.com/egtra/2016/04/19/878/

ということで、検索結果にしたがってランタイムを正しいものに更新。するとDEBUGビルドは直ったのだが、RELEASEビルドが直らない。

DependencyWalkerで探ってみても、アプリとOpenCVとで呼び出しているランタイムは全く同じに見える。

結局、VS2013のアンインストール、VS2015の修正などさんざん試行錯誤したあげく、試しにOpenCV3.1.0をビルドしてリンクするとエラーが無くなった。 公式のビルド済みバイナリも、VC14バージョンの提供はOpenCV3.1.0からだから、OpenCV3.0 と Visual Studio2015(VC14)に問題があったのかな?それともOpenCVも全てソースからビルドしているわけでは無いので、ビルド済みバイナリのどれかが問題になったのかもしれない。

というわけで、使っているAPIが全て問題無く動作することを確認した上で、OpenCV3.0.0を捨てて3.1か3.2に移行する予定。

結論

ビルド&テスト済みのバージョンの組み合わせ以外は疑ってかかるべし

追記

OpenCVVisual Studioビルドでハマッタ時のレシピ 基本的には、以下の手順でビルドできます。

  1. OpenCVソースコードOpenCV libraryから取ってくる
  2. CMAKEでビルドする
  3. 作られたslnファイルを開き(Visual studio起動)ビルドする
    • DEBUGもしくはRELEASEで、ALL_BUILDを実行する。INSTALLをビルドすると、指定したinstallディレクトリにバイナリとincludeファイルをコピーしてくれる
ビルド失敗ケース
  1. CMAKEのconfigureが失敗する
    • プロキシ認証がある環境だと、ippicvやffmpegなどの3rd party製バイナリをダウンロード出来ずにhashチェックで失敗することが多い。この場合アドレスを調べ、手作業でダウンロードし、必要なディレクトリにコピーする(必要な場所はCMAKEに表示される)
  2. ビルドは成功したものの、実行時に落ちる
    • 一番多いのは、ライブラリのビルド時と、アプリケーション側のビルド時の設定が異なっているケース。まずはランタイムライブラリがちゃんと同じになっているか確認する。(マルチスレッド・マルチスレッドDLL・マルチスレッドデバッグDLLなど)
    • バージョンの組み合わせを疑う