VS2008+DDK2003下如何重定义eh.lib中已存在的函数?
解决VS2008+DDK2003下type_info::name()重复定义问题
这个场景我太熟悉了——老DDK和新VS的CRT库在C++ RTTI实现上的冲突,本质是DDK2003的eh.lib里自带了一个type_info::name()的实现,和VS2008标准库的实现撞车了。要让你自己的(或者说VS2008标准头文件对应的)定义生效,按下面的步骤来:
方法1:调整链接顺序(最推荐)
链接器是按“先到先得”的规则处理符号的,所以只要把包含正确定义的文件/库放在eh.lib前面,就能覆盖掉它的实现:
- 如果是VS项目:
- 右键项目 → 属性 → 链接器 → 输入 → 附加依赖项
- 把VS2008的CRT库(比如
msvcrt.lib对应多线程DLL,libcmt.lib对应多线程静态)放在eh.lib的前面 - 或者直接去「链接器 → 命令行」,在附加选项里写:
msvcrt.lib eh.lib(按你实际用的CRT库调整)
- 如果是DDK的
sources脚本:
修改TARGETLIBS的顺序,把CRT库排在eh.lib之前,比如:TARGETLIBS=$(CRT_LIB_PATH)\msvcrt.lib $(DDK_LIB_PATH)\eh.lib
方法2:强制链接器优先使用你的实现
如果调整顺序还不行,你可以把自己的type_info::name()定义单独放在一个.cpp文件里,编译成obj后,在链接时把这个obj放在所有库的最前面:
- 在VS项目属性的「链接器 → 输入 → 附加依赖项」最开头加上你的obj文件名,比如
mytypeinfo.obj eh.lib ... - 这样链接器会先加载你的obj里的定义,后面
eh.lib里的重复定义就会被自动忽略
方法3:忽略重复定义警告并强制使用你的版本
如果上面的方法都没效果,可以直接告诉链接器忽略这个重复定义的警告,并且强制使用你的实现:
- 打开项目属性 → 链接器 → 命令行
- 添加两个选项:
/IGNORE:4006:忽略“符号已定义”的警告(警告代码4006就是你遇到的那个)/FORCE:MULTIPLE:允许链接器跳过重复定义的冲突,优先使用先找到的符号
- 别忘了把你的obj或者CRT库放在
eh.lib前面,确保先加载正确的定义
注意事项
- 每次修改链接设置后,一定要Clean解决方案再重新构建,避免旧的编译产物干扰结果
- 注意CRT的版本匹配:如果DDK2003用的是静态CRT,你的VS项目也要对应设置成
/MT(多线程静态),如果是动态则用/MD,不匹配的话可能会引发其他奇怪的问题 - 如果你是要完全重写
type_info::name()的逻辑,记得确保你的定义和标准头文件里的声明完全一致:const char* type_info::name() const,参数、返回值、const修饰都不能错,否则会导致链接错误或者运行时崩溃
内容的提问来源于stack exchange,提问作者Vishal Gaikwad
相关产品推荐
相关产品推荐

