vs2010+OpenCV静态编译

静态编译vs.动态编译

程序中需要用到第三方库时,要使得程序在别的电脑上也能正常运行,通常有两种方式:

  • 动态编译。即在程序运行时动态加载第三方库,这时候就需要把涉及到的第三方库的dll和exe文件放在同一目录下。优点是exe文件比较精简,而且如果第三方库有更新,替换掉相应dll文件即可,可维护性和升级性强。缺点是exe运行时需要附带很多dll文件,比较麻烦,而且有潜在的由于dll版本不一样带来的兼容性问题。
  • 静态编译。即在程序编译生成时,把第三方库的代码嵌入到要生成的exe文件中,这样单个exe文件就能在其他电脑上运行。优点是单个exe文件即可执行,直观简洁。缺点是exe文件较大,而且第三方库更新时需要重新编译。

vs2010静态编译设置

要想在visual studio中静态编译程序,需要有两处地方进行设置。

  • 项目->属性->配置属性->C/C++->代码生成->运行库

运行库下面有四个下拉选项,选项及含义见下表:

选项 含义
多线程(/MT) Release下的静态编译
多线程调试(/MTd) Debug下的静态编译
多线程DLL(/MD) Release下的动态编译
多线程调试(/MDd) Debug下的动态编译

以Release模式为例,把运行库选项改成多线程(/MT)即可

  • 项目->属性->配置属性->常规->项目默认值->MFC的使用

其默认值为使用标准Windows库,将其改成在静态库中使用MFC即可

OpenCV静态编译

设置静态库目录

接下来是设置OpenCV的静态编译了。现在的OpenCV直接带有静态编译的链接库版本,无需自己重新编译,在%opencv_dir%/build/x86/vc10/staticlib目录下。

项目->属性->配置属性->VC++目录->库目录

把上面的静态库目录添加进去即可。

设置附加依赖项

项目->属性->配置属性->连接器->输入->附加依赖项,进行设置即可。

OpenCV相关依赖项

在OpenCV中staticlib目录中的lib文件和lib目录中的文件命名方式是一样的,把程序中用到的库文件添加进去,比如:

1
opencv_core247d.lib
opencv_features2d247d.lib
opencv_flann247d.lib
opencv_highgui247d.lib
opencv_imgproc247d.lib

从staticlib目录可以看到,除了跟动态库一样的以opencv_开头的库之外,还有以下几个,也需要一并添加进去:

1
IlmImfd.lib
libjasperd.lib
libjpegd.lib
libpngd.lib
libtiffd.lib
zlibd.lib

系统相关

设置好OpenCV相关的依赖项之后,如果此时编译,则会出现很多类似于下一句的错误:

1
1>opencv_highgui247d.lib(window_w32.obj) : error LNK2019: 无法解析的外部符号 __imp__GetSystemMetrics@4,该符号在函数 _xGetSystemMetrics@4 中被引用

这是因为缺少了一些系统所需要的库。

如果注意观察的话,可以发现,在动态编译时,附加依赖项设置页面下方有“继承的值”一项(从父级或项目默认设置继承)。而改成
静态编译之后,这些默认值没有了,所以需要手动添加。

1
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib

设置好上面这些依赖项之后,直接编译还是会出现以下错误:

1
1>opencv_highgui247d.lib(window_w32.obj) : error LNK2019: 无法解析的外部符号 __imp__CreateToolbarEx@52,该符号在函数 "int __cdecl icvCreateTrackbar(char const *,char const *,int *,int,void (__cdecl*)(int),void (__cdecl*)(int,void *),void *)" (?icvCreateTrackbar@@YAHPBD0PAHHP6AXH@ZP6AXHPAX@Z3@Z) 中被引用

这时候添加下面这个lib文件即可

1
comctl32.lib

至此,vs2010+OpenCV的静态编译设置就完成了,此时编译生成的程序,就可以放在其他电脑直接运行了,而无需拷贝一堆dll文件。