error LNK2038: mismatch detected 这个错误,是在VS2010开始才出现的,出现这个错误通常是你编译出一个静态库,然后别一个工程里引用这个静态库,而两者编译方式不一样,一个debug,一个release时,往往会出现这个错误。此问题也是misakamm在写ege的时候所曾经碰到的问题。
  它的核心是VS2010新增加的一个#pragma指令detect_mismatch
  这里是MSDN官网的解释,内容全英文:http://msdn.microsoft.com/en-us/library/ee956429.aspx
  misakamm知道有人会不爽的,misakamm就在这简单的翻译一下:

detect_mismatch
放置一个记录到obj里(就是编译出来的obj文件,通常对应两个cpp文件),链接器会对这个记录做匹配测试

语法:#pragma detect_mismatch( “name”, “value”))

注意:
  当你链接你的项目的时候,如果两个obj文件有相同的name字段,却value不一样的时候,链接器会抛出2038号错误。使用这个pragma来解决obj的一致性问题。
  而name和value都应该是一个字符串常量。并且它们大小写敏感,均不能包含逗号,引用,等号和’\0′。

示例:
以下例子建立两个文件,有不同的版本号,但使用同一个版本号标签

1
2
3
4
5
6
7
8
9
// pragma_directive_detect_mismatch_a.cpp
#pragma detect_mismatch("myLib_version", "9")
int main ()
{
   return 0;
}
 
// pragma_directive_detect_mismatch_b.cpp
#pragma detect_mismatch("myLib_version", "1")

当你把这两个文件放在同一工程里编译链接的话,你就会得到2038号错误


  好了,解释完这个错的产生的根本原因,然后就是分析它和解决它的时间了。
在VS2010的C++头文件(包括STL)里,都会包含yvals.h这个文件,而这个文件会定义:
#pragma detect_mismatch(“_ITERATOR_DEBUG_LEVEL”, “xxxxxx”)
其中,xxxxxx中的内容,会因为你的编译方式不同,而使用不一样的值。于是乎,在你链接两个使用不同编译方式的东西的时候就会报这个错了。

  解决方法一是,保证两个模块使用相同的编译方式,这是最好的做法。
  但如果你需要发布静态库,那么一种编译方式发布一个lib是很麻烦的事情,那么就需要第二种解决方法,就是屏蔽检测。而决定要不要做这个匹配性检测的宏,是_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
  所以,只需要在你包含标准库之前,加入一行
#define _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
就像:

1
2
3
4
5
6
7
8
9
#define _ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH
#include xxxxxx
#include xxxxxx
 
int main() {
    xxxx;
    xxxx;
    return 0;
}

又或者,在你要编译的静态库工程里每个cpp最开头都写上那么一句,问题就解决了