关于VC静态库的连接问题

来源:互联网 发布:java单元测试覆盖率 编辑:程序博客网 时间:2024/06/07 17:48


最近在搞一个图形程序的发布, 其中用到了某个图形引擎的静态库, 该静态库仅提供了release版本的库, 在我编写的程序需要提供debug和release两种版本, 这样在连接静态库时Debug版本编译时倒也通过了, 不过运行时弹出 crt的堆指针错误"_ASSERTE( _CrtIsValidHeapPointer( xxx ) );, 但在release版下就没有问题.
经过一阵查找和琢磨, 终于清楚了一些:

vc的静态库编译时需要选择C运行时库的版本, 以VC6为例进行说明:

在VC的工程设置页上C/C++=>Category[Code Generation]中的Use run-time library 下拉框中包含如下选项
1. Single threaded*
2. Multithreaded
3. Multithreaded DLL
4. Debug Single threaded*
5. Debug Multithreaded
6. Debug Multithreaded DLL
上述选项对应的连接库位
1. libc.lib
2. libcmt.lib
3. msvcrt.lib
4. libcd.lib
5. libmtd.lib
6. msvcrtd.lib

静态库连接的运行时库如果和主程序使用的运行时库的版本不一致, 那么就会出现连接错误或者运行时出错.

我经过查看, 发现那个图形引擎的静态库使用的MSVCRT.LIB, 而我的程序利用向导生成的debug版使用的MSVCRTD.LIB
因此会有问题, 所以我把debug版的运行时库也调整为MSVCRT.LIB, 但编译时始终提示
error LNK2001: unresolved external symbol __imp___CrtDbgReport
后来我把_DEBUG标识去掉结果就好了,
 
反推想应该是CrtDbgReport为MSVCRTD.LIB导出的一个函数而在MSVCRT.LIB中没有此函数, 可能在c/c++标准库中的某个地方如下语句:
#ifdef _DEBUG
...
CrtDbgReport(...);
...
#endif

因此在使用静态库方面, 我总结出如下经验:
首先要判定要连接的静态库使用的运行时库的版本
然后按照静态库使用的运行时库来调整主程序的运行时库

然而如果需要连接多个静态库而且它们使用了不同版本的运行时库, 那可能就麻烦了, 具体解决方法还不太清楚.