基於OpenCV的程序脫離動態鏈接庫運行方法

題目來自OpenCV·China的每週一練:

我們在做項目時,通常需要把依賴於opencv,vs(例如vs2005),或者vc(例如vc6.0)的程序,在沒有安裝相關環境的電腦上去運行。那麼現在有哪些方法可以擺脫這些依賴?(提供可行建議即可得10分)

http://www.opencvchina.com/thread-1368-1-1.html

解決方法:

首先要明確在沒有安裝OpenCV的電腦上,要運行基於OpenCV庫的程序,有兩種方法:一、將OpenCv安裝目錄下的bin目錄下的*.dll文件 與應用程序一起打包發佈。

二、將OpenCV庫源代碼加載到工程中和應用程序一起編譯,也就是說最後生成的可執行文件可以單獨運行,不需要OpenCV的動態鏈接庫。下面將詳細介 紹這種方法。

 

首先要確定程序使用了OpenCV的哪些庫函數,一般來說,cv、cxcore和highgui是必需的,爲簡化說明,下面將只編譯這三個庫,如果有使用 其它庫,同樣也要加入。系統環境爲:WindowsXP+VC6.0+OpenCV1.0。

1、  爲方便管理,先將OpenCv安裝目錄下的cv、cxcore、otherlibs/highgui三個目錄複製到你的工程目錄。

2、  在集成開發環境的項目管理窗口中(FileView)新建兩個文件夾,分別爲opencv_src,opencv_include。

3、  在項目管理窗口中右擊opencv_include項,選擇Add Files to Folder...,將第1步中已複製至工程目錄下的三個目錄下的include目錄中的.h文件添加到該項目管理文件夾中。接着按相同做法將三個目錄下 的src目錄中的.cpp文件添加到opencv_src項目管理文件夾中。

4、  幾點注意:dummy.cpp在三個目錄下都有,只需要添加一次。Highgui目錄下以cvcap開頭的.cpp文件爲攝像頭相應庫,如果你的程序沒有 處理視頻,不要添加這些.cpp文件。不要添加window_carbon.cpp文件,原因還不明。

5、  右擊opencv_src,選擇Setting...,選擇C/C++頁,在Category選擇Precompiled Headers,再選擇下面四個單選項中的第一項”Not using precompiled headers”。這樣做的目的是不使用編譯頭文件,否則會產生“找不到文件結尾”的錯誤。也可以在每個.cpp文件的開頭加入include ”stdafx.h”,但顯然沒有更改一個選項來得方便。

6、  在Project->Settings...->C/C++中,選擇Category中的Preprocessor項,把 Additional include directories改爲cv/include,cv/src,highgui, cxcore /include, cxcore /src

7、  Project->Settings...->Link,如果Object/library modules中有cv.lib,cvaux.lib,highgui.lib,刪除之

補充:

OpenCV的安裝

我們下載的OpenCV安裝包一般包括源碼,示例,文檔和編譯好的動態鏈接庫(以前OpenCV可能需要自己編譯一遍,OpenCV2.3.1之後都有一個build的文件夾,有編譯好的mingw,vc9和vc10的版本)。
我們寫代碼如果調用OpenCV的函數,需要添加附加依賴項:
Include Directories :C:\OpenCV\OpenCV-2.4.2\build\include
Library Diractories:C:\OpenCV\OpenCV-2.4.2\build\x86\vc10\lib
然後還需要在Linker->Input->Additional Dependencies裏添加會用到的各種XX.lib,XXd.lib
還有把兩個bin文件夾:
C:\OpenCV\OpenCV-2.4.2\build\x86\vc10\bin
C:\OpenCV\OpenCV-2.4.2\build\common\tbb\ia32\vc10
添加到系統環境目錄
有的安裝教程裏還會教我們在Source Directories添加OpenCV的源碼文件,其實是不需要的。因爲實際調用OpenCV裏的函數是用的dll的隱式調用方式。

DLL調用

隱式調用一般需要:

聲明函數接口的.h文件——include文件夾裏的內容
鏈接動態庫的.lib文件——lib文件夾裏的內容以及Input->Additional Dependencies添加的XX.lib
動態鏈接庫.dll文件——bin文件夾的內容
這裏bin文件夾是在系統環境目錄裏的,所以執行代碼是exe文件可以找到。也可以添加在系統文件中,把需要用到的dll拷貝到exe同一個文件夾下即可。
所以,如果把未發佈的工程拷貝到沒有opencv的電腦上,只要把需要用的函數相關的.h,.lib以及.dll文件考過去即可。


另一種調用dll的方式是顯示調用:

顯示調用是不需要.lib和.h文件的,只會用到dll文件。

但需要在代碼裏“顯示”加載要用到的函數。例如:

  1. HINSTANCE hDLL=NULL;//生命DLL句柄    
  2. hDLL=LoadLibrary("opencv_core242d.dll");  //加載DLL  
  3. HMAT myImread=(HMAT)GetProcAddress(hDLL,"imread");  //使用DLL中的函數  
這樣在拷貝工程時只拷貝用到的DLL文件就可以。
但這樣代碼寫得很麻煩,DLL換個名字版本之類的要改很多地方,一般用得不多。

靜態編譯的exe程序

如果只是給別人靜態鏈接的exe程序,比如一個demo,不用跑程序。

最常用的方法就是一起拷貝exe和dll文件到目標電腦:
也就是將需要用到的dll文件拷到exe文件夾下即可,Release拷貝XX.dll,Debug版本拷貝XXd.dll
(所以我們寫Additional Dependencies不用到的儘量不寫,這樣拷的dll會少一些~)


再一種方法就是樓上提到的把OpenCV的源碼一起編譯到可執行文件中。

這種需要在寫代碼時把OpenCV的源文件加入到工程中。也就是用到的.cpp文件目錄添加到Source Directories項中。
編譯頭文件可能會遇到"找不到文件結尾”之類的錯誤,在項目屬性Category中選擇"Precompiled Headers"和"Not using precompiled headers"即可。

這樣工程不是調用的OpenCV編譯過的dll文件,而是把OpenCV當成你自己寫的文件一樣一起編譯。

在沒有安裝OpenCV的電腦上只用拷貝最終的exe文件即可。不需要dll文件,只是生成的exe會比較大~

原博文:

http://blog.csdn.net/xiaowei_cqu/article/details/8066329

http://blog.csdn.net/charles_3081523/article/details/5765920

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章