warning LNK4070的解决办法

本文详细解释了如何解决在MFC常规DLL工程重命名后出现的警告LNK4070问题,主要涉及到修改def文件中的LIBRARY字段以确保输出文件名与def文件一致。此外,还讨论了在生成DLL时遇到类似警告的解决方案,包括删除自动生成的def文件或修改其内容。文章提供了多个实用技巧和方法,帮助开发者避免此类警告对项目构建过程的影响。

warning LNK4070的解决办法

作者:朱金灿
来源: http://blog.youkuaiyun.com/clever101

       重命名了一个MFC常规DLL的工程文件(VS C++ 2005编译环境),结果在编译时出现这样的警告:1>B.exp : warning LNK4070: .EXP 中的 /OUT:A.dll 指令与输出文件名"..\outdir\Debug\B.dll"不同;忽略指令(这里假设原来的工程文件名叫A.vcproj,改名后叫B.vcproj)。后来我发现虽然输出为B.dll,但是对应的静态库B.lib被其它工程以隐式链接的方式调用时,使用的还是A.dll(这个可以使用Dependcies工具来查看),这样导致往往其它动态库不能加载成功(因为)。这下我不能把它仅仅当做warning而弃之不管了,于是上网查资料解决这个warning。查完资料,再结合自己的思考,大致明白了造成warning的原因。原来是虽然我修改了工程名,但是没有修改这个工程的def文件中LIBRARY字段的值,造成工程的输出文件和def文件的LIBRARY字段的值不一样。比如我把A.vcproj修改为B.vcproj,但在def文件还是LIBRARY "A"。这时只需将def文件中的LIBRARY字段修改为:LIBRARY "B"。这样就能完全消除这个警告。而被别的库以隐式链接调用也是以B.dll面目出现的。
 

链接警告:warning LNK4070: /OUT:dll.dll directive in .EXP
 

在生成dll时候经常出现lnk4070警告,尽管可能不会影响使用,但是也造成了一些麻烦诸如明明debug和release版本的lib名字不一样,可是exe却总是去找release版本的(debug的为结尾加了d的)。其实一直不晓得这个是怎么回事,也懒得去弄清楚了,反正能用就行了。今天看到一篇文章,恍然大悟!原来问题在这里,就是这个小小的warning造成了这一切。

先转帖如下: 引自地址http://hi.baidu.com/sonmeika/blog/item/726d47d0ccc5578ca1ec9c70.html

我在DLL项目中遇到了,因为要对Debug版和Release版分别指定不同的输出文件名。对Debug版,我指定输出文件为dllD.dll,对Release版指定为dllR.dll。

解决方法有两个:

(1)删掉自动生成的dll.DEF文件,在代码中使用_declspec(dllexport)导出函数;

(2)删掉dll.DEF文件中LIBRARY字段后面双引号及其内部的库名即可,也可以将其改掉。如改为:******************************************************************************************  

dll.def : Declares the module parameters for the DLL.  

LIBRARY      "dllD"
DESCRIPTION 'dll Windows Dynamic Link Library'              

EXPORTS    ; Explicit exports can go here
******************************************************************************************
还有更好方法:
1.生成两份DEF文件,
           xx.def //Release版本
           xxD.def //Debug版本
2.把这两个文件都添加到项目中
3.只要在Debug项目的Setting中选中xx.def,在右边的General中在Exclude file from built前打勾
同样在Release项目的Setting中选中xxD.def,在右边的General中在Exclude file from built前打勾
4.接下来就Betch Build吧

### 问题分析 警告 `LNK4098` 表示项目中存在多个 C 运行时库(CRT)的冲突,通常是以下原因导致的: 1. **混合使用不同版本的 CRT**: - 例如,某些库静态链接了 `MSVCRT.lib`(旧版调试库),而其他库动态链接了 `MSVCRTD.lib`(新版调试库)或 `LIBCMT.lib`(多线程静态库)。 2. **第三方库的编译设置不匹配**: - 第三方库可能使用了与主项目不同的运行时库(如 `/MT` vs `/MD`)。 3. **调试版与发布版混用**: - 调试版(带 `D` 后缀,如 `MSVCRTD.lib`)和发布版(如 `MSVCRT.lib`)混用。 --- ### 解决方法 #### 方法 1:统一运行时库设置 1. **在 Visual Studio 中**: - 右键项目 → **属性** → **C/C++** → **代码生成** → **运行时库**。 - 确保所有项目和依赖库使用相同的选项: - `/MD`:动态链接多线程库(`MSVCRT.lib`)。 - `/MDd`:动态链接多线程调试库(`MSVCRTD.lib`)。 - `/MT`:静态链接多线程库(`LIBCMT.lib`)。 - `/MTd`:静态链接多线程调试库(`LIBCMTD.lib`)。 - **推荐**:优先使用 `/MD` 或 `/MDd`(动态链接更节省空间)。 2. **检查第三方库**: - 如果第三方库是预编译的,确保其编译时的运行时库设置与项目一致。 - 必要时重新编译第三方库。 --- #### 方法 2:忽略冲突库(`/NODEFAULTLIB`) 如果无法统一运行时库,可以通过 `/NODEFAULTLIB` 忽略冲突的库: 1. **在项目属性中**: - **链接器** → **输入** → **忽略特定默认库**,添加冲突的库名(如 `MSVCRT.lib` 或 `LIBCMT.lib`)。 - 或直接在代码中添加编译指令: ```cpp #pragma comment(linker, "/NODEFAULTLIB:MSVCRT.lib") ``` 2. **手动指定链接库顺序**: - 在 **链接器** → **输入** → **附加依赖项** 中,显式指定需要的库(如 `MSVCRTD.lib`)。 --- #### 方法 3:检查依赖项冲突 1. **使用 `dumpbin` 工具**: - 运行以下命令查看库的依赖项: ```bash dumpbin /directives yourlib.lib | find "MSVCRT" ``` - 确认是否有混合的 CRT 引用。 2. **修复依赖项**: - 如果某个库强制引用了错误的 CRT,尝试替换该库或联系供应商提供匹配的版本。 --- ### 验证修复 1. 清理解决方案并重新生成。 2. 检查输出窗口,确认 `LNK4098` 警告是否消失。 --- ### 关键点总结 - **根本原因**:运行时库(CRT)版本冲突(如 `/MT` vs `/MD`)。 - **推荐方案**:统一所有项目和库的运行时库设置(优先动态链接 `/MD`)。 - **临时方案**:通过 `/NODEFAULTLIB` 忽略冲突库,但需谨慎使用。 - **调试技巧**:使用 `dumpbin` 或 Dependency Walker 检查库依赖。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值