プログラマのつれづれなるままにプログラマのつれづれなるままに音宮志久が思ったことなどをネタにします。プログラムネタ・数学ネタがメインです。OpenCVのライブラリには要注意OpenCVのライブラリには要注意コメントを残すちょっとはまってしまったネタなので書いてみます。OpenCVのライブラリにある「結果データをSTLにあるvectorで返す」処理がいろいろと知らないと簡単にバグを起こして立ち往生しますので。2.4系)だとVisualStudio2005を使ってやろうとしている人がはまります。VisualStudio2008やVisualStudio2010ならばすでにそれようにコンパイルされたライブラリもしくはDLLがあるのでそれを使えばこの問題にはまることはあまりありません。それでも、DLLを使うときにはやはり注意する必要があります。処理としては、典型的なのがcv::imencodeを使ったイメージの変換作業です。メモリ上で変換を行ってくれるのでOpenCVでは結果の送受信等に使われます。STLのvectorが動的確保を行うときにはランタイム内のメモリ処理が使われるというか、STLのライブラリがメモリ確保を行うときは基本的にはnew演算子を使ってメモリ確保を行うことと同じような動作を行います。ここにとんでもない落とし穴があります。この話題については過去にちょっと触れている問題ですが、これが大きくなってしまった物です。VisualStudio2008(or2010)で構築されたDLLをVisualStudio2005で構築されたEXEに連結すると?と言う話です。EXE側はもちろんVisualStudio2005のランタイムライブラリを連結しますのでそれに準拠したメモリ処理が行われます。ところが、DLL側はVisualStudio2008のランタイムライブラリを連結しますので、相互にまたいでのメモリ処理に互換性が全くなくなります。すると、初めに上げたパターンである「OpenCVのライブラリ内でvectorによるメモリの動的確保を行い、実行ファイル側でそのメモリを解放しようとする」と、状態が整合できないのがわかると思います。ちなみに、両方ともVisualStudio2008であったとしても、EXE側には静的ランタイムライブラリを結合しているDLL側も同様に(自分だけで)静的ランタイムライブラリを結合しているだと、ランタイム内にそれぞれがヒープメモリを管理しているならやはり整合はとれません。OpenCVのvectorを使う処理を使うときは「静的リンク+ランタイムライブラリをそろえる」もしくは「動的リンク+同一のDLLのランタイムライブラリを使用する」とする必要がありちなにみ、OpenCV2.4ではVisualStudio2005のライブラリはありませんので、CMakeを使ってVisualStudio2005のプロジェクトを作成してコンパイルする必要があります。それでコンパイルして静的リンクを行うのであれば同一のメモリ管理で扱われるのでめでたしめでたし、となります。いわゆる「DLLでメモリをnewで確保して、EXEでメモリをdeleteで解放する」の問題の解決パターンになります。コメントをキャンセルメールアドレスが公開されることはありません。気になるプログラムネタや数学ネタがあったら書き込みたいのだが残業が長すぎて眠気が全くとれず体調があまりよくない。過労などでぶっ倒れるかもしれない。あと、さすがに独り身が寂しいのでなんとかしたいと考えてはいるのだが...。アクセスカウンタアクセス数:スポンサーリンクモバイルバージョンに。