Windows上,习惯将debug模式下生成的动态库名后缀添加D 以作和release区分。
debug和release的动态库是否可以混用
现象
使用一些第三方的dll,比如opencv,会分别生成debug和release的dll,在exe中必须要引用指定版本的dll,不能混用,否则会出错;
但是还有一些第三方的dll,比如halcon,只提供给用户release的dll,用户的debug版和release版的exe都可以引用此dll。
原因
比如debug的exe调用release编译生成的dll,接口函数的参数如果使用std::vector或者std::string之类的东西,肯定会崩。因为stl在release和debug下实现不同。std::string在debug和release环境中的内存大小是不一致的。 如果混用,会出现内存奔溃现象。
结论
不含stl库的debug动态库和release动态库在debug或release项目中都可以使用;
含有stl的debug动态库和release动态库在项目中不能混用,debug项目必须用debug库,release项目必须用release库 ;
内存谁分配谁释放,动态库导出函数不要用stl,仅使用基本类型或接口;
cmake中配置debug与release的对应库
cmake创建一个项目A,A引入动态库B,cmake怎么配置A链接动态库B的debug和release对应的库呢。
通过配置target_link_libraries的参数可以进行配置:
1 | target_link_libraries(${PROJECT_NAME} PRIVATE |
其中。${sdk_LIBRARY_debug}是动态库debug模式下的绝对路径。 同理,${sdk_LIBRARY_release}是动态库release模式下的绝对路径。而他们的定义通过再findsdk.cmake文件中配置:
1 | FIND_PATH(sdk_INCLUDE_DIR sdk.h ${CMAKE_CURRENT_SOURCE_DIR}/sdk/include) |
后续使用通过find_package(sdk)。
如何生成debug和release的动态库
Debug的动态库一般有后缀d
,在CMakeLists.txt中添加:
1 | set(CMAKE_DEBUG_POSTFIX d) |
这样编译出来的Debug版本的动态库就有了d
。
CMakeLists.txt文件的编译命令:
1 | cmake . -B build # create build dir |
release生成pdb调试文件
CmakeLists.txt中添加以下内容,可生成pdb文件,在调试dump文件时有用。
1 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi -DQT_MESSAGELOGCONTEXT") |
上面的可以按需组合或无脑全加入CMakeLists.txt。需要添加三行标志:
- 第一行:告诉编译器生成调试信息
- 第二行:告诉链接器生成exe时加入调试信息
- 第三行:告诉链接器生成dll时加入调试信息