2011年11月29日星期二

在Debug和Release模式下编译执行不同的代码

关于Debug和Release最常见的问题就是:“这个DLL到底是Debug build还是Release build?”对于这个问题可以在网上找到各种解答,本文也不想讨论它。本文要说的是:如何在Debug和Release模式下编译执行不同的代码。

问题的来源是:最近用OpenCV做图像处理,需要将OpenCV的lib静态链接到我的程序,从而能够把我的程序拿到别的没有OpenCV的机器上运行。用#pragma comment就可以把链接库包括进来。但是Debug和Release时需要分别调用OpenCV库的Debug和Release版本,这样岂不是要在Release之前再改一次代码。

解决的方法是:如果是Debug模式编译,会自动定义_DEBUG宏,如果是Release则没有定义_DEBUG,(是否在Release模式下定义_RELEASE我就不知道了,有兴趣的可以一试)我们只需要利用预编译宏#ifdef就可以解决问题。
#ifdef _DEBUG
#pragma comment(lib, "opencv_core231d.lib")
#pragma comment(lib, "opencv_imgproc231d.lib")
#pragma comment(lib, "opencv_highgui231d.lib")
#else
#pragma comment(lib, "opencv_core231.lib")
#pragma comment(lib, "opencv_imgproc231.lib")
#pragma comment(lib, "opencv_highgui231.lib")
#endif
如上例Debug时程序将链接文件名带字母d的OpenCV库Debug版本,Release时将链接OpenCV库的Release版本。此处要注意_DEBUG的大小写和前面的下划线。
其他适用此方法的情况:很多情况下,需要在调试程序时输出一些调试信息,但不希望在发布程序中出现这些调试信息。我之前的做法是调试时用printf或MessageBox输出,Release时将调试用到的printf和MessageBox注释掉。但是当注释很多时就很麻烦了。如果利用前面的方法,在需要注释的语句前后分别加上#ifdef DEBUG和#endif这个问题就不再是问题了,无论Debug还是Release都不用再改动代码了。例如
#ifdef _DEBUG
printf(......);
#endif
上面的printf语句就只在Debug时编译,Release时将无视。
PS:我仅使用Visual Studio 2010,所以我所做的实验也是基于它的,之前的visual studio版本应该也适用,其他编译环境就无从考证了。

阅读全文...