libcmtd.lib(crt0dat.obj) : error LNK2005: _exit already defined in msvcrtd.lib(MSVCRTD.dll) 编译错误解决方法

本文介绍了解决VC6环境下编译G279软件时出现的链接错误的方法。通过调整项目设置,如使用/NODEFAULTLIB指令屏蔽默认库libcmtd.lib,解决了由静态CRT库与MFC共享DLL配置之间的冲突导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[问题描述]

今天在VC6下编译G279软件时,已编译通过,链接时报一下错误:

Linking...
libcmtd.lib(crt0dat.obj) : error LNK2005: _exit already defined in msvcrtd.lib(MSVCRTD.dll)
libcmtd.lib(crt0dat.obj) : error LNK2005: __exit already defined in msvcrtd.lib(MSVCRTD.dll)
libcmtd.lib(strcat.obj) : error LNK2005: _strcpy already defined in msvcrtd.lib(MSVCRTD.dll)
libcmtd.lib(winxfltr.obj) : error LNK2005: __XcptFilter already defined in msvcrtd.lib(MSVCRTD.dll)
libcmtd.lib(crt0init.obj) : error LNK2005: ___xc_z already defined in msvcrtd.lib(cinitexe.obj)
libcmtd.lib(crt0init.obj) : error LNK2005: ___xc_a already defined in msvcrtd.lib(cinitexe.obj)
libcmtd.lib(crt0init.obj) : error LNK2005: ___xi_z already defined in msvcrtd.lib(cinitexe.obj)
libcmtd.lib(crt0init.obj) : error LNK2005: ___xi_a already defined in msvcrtd.lib(cinitexe.obj)
libcmtd.lib(atox.obj) : error LNK2005: _atoi already defined in msvcrtd.lib(MSVCRTD.dll)
msvcrtd.lib(MSVCRTD.dll) : error LNK2005: _strncpy already defined in libcmtd.lib(strncpy.obj)
msvcrtd.lib(MSVCRTD.dll) : error LNK2005: __snprintf already defined in libcmtd.lib(snprintf.obj)
msvcrtd.lib(MSVCRTD.dll) : error LNK2005: __setmbcp already defined in libcmtd.lib(mbctype.obj)
LINK : warning LNK4098: defaultlib "msvcrtd.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
msvcrtd.lib(cinitexe.obj) : warning LNK4098: defaultlib "libcmtd.lib" conflicts with use of other libs; use /NODEFAULTLIB:library
libcmtd.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/LanVoice.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

LanVoice.exe - 14 error(s), 2 warning(s)
这样的问题在以前也遇到过,只是没有在意,细细想一想,问题的原因上面已经指出,就是红色那一句,默认的"libcmtd.lib"和其他的一些libs有冲突,可以用/NODEFAULTLIB:library设置屏蔽掉默认的libcmtd.lib

在Project中打开Project Setting设置对话框,选择Link选中Category旁边下拉框的Input项。

在Ignore Libraries下面输入libcmtd.lib,将此屏蔽。

重新编译,链接,结果却大失所忘, 刚才的错误解决了,但新的错误却又出现了:

Linking...
LINK : warning LNK4049: locally defined symbol "_atoi" imported
LINK : warning LNK4049: locally defined symbol "_strncpy" imported
LINK : warning LNK4049: locally defined symbol "__snprintf" imported
LINK : warning LNK4049: locally defined symbol "__setmbcp" imported
jrtplib.lib(rtprandom.obj) : error LNK2001: unresolved external symbol __imp__srand
jrtplib.lib(rtprandom.obj) : error LNK2001: unresolved external symbol __imp__clock
jrtplib.lib(rtprandom.obj) : error LNK2001: unresolved external symbol __imp__time
jrtplib.lib(rtprandom.obj) : error LNK2001: unresolved external symbol __imp___getpid
jrtplib.lib(rtprandom.obj) : error LNK2001: unresolved external symbol __imp__rand
jthread.lib(jthread.obj) : error LNK2001: unresolved external symbol __imp___beginthreadex
Debug/LanVoice.exe : fatal error LNK1120: 6 unresolved externals
Error executing link.exe.

LanVoice.exe - 7 error(s), 4 warning(s)
不要泄气,既然冲突是双方产生的,那一定就是屏蔽的库不对了,应该屏蔽这个库libcmtd.lib

果然重新编译一切OK。

回过头来,原来我的程序是USE mfc  in a share dll, libcmtd.lib是静态 C runtime库,所以应该屏蔽掉libcmtd.lib,以免造成冲突。

<think>我们正在解决一个MFC项目中调用Haru库时出现的LNK2005链接错误。根据用户描述,错误涉及到libcmtd.libMSVCRTD.lib之间的冲突。这通常是由于项目中混用了不同版本的运行时库(例如,一个库使用调试版,而另一个使用发布版,或者同时混用了静态和动态链接的运行时库)导致的。参考引用中提到了Haru库的最新版进行了完全重写,可能因此改变了其库的构建方式,导致与MFC项目的兼容性问题。典型的解决方案是确保整个项目(包括所有依赖库)使用相同的运行时库设置。在MFC项目中,我们可以通过以下步骤调整:1.检查Haru库的构建方式:确认Haru库是使用哪种运行时库(Debug/Release,静态/动态)构建的。通常情况下,如果Haru库是用动态链接的运行时库(如/MD或/MDd)构建的,那么我们的项目也要使用相同的设置。2.调整项目的运行时库设置:-在VisualStudio中,右键项目->属性->C/C++->代码生成->运行时库。-确保项目配置(Debug/Release)与Haru库的配置匹配。例如:-Debug配置:使用/MDd(如果Haru库在Debug下使用动态链接)或者/MTd(如果使用静态链接,但注意混用可能引发问题)。-Release配置:使用/MD或/MT。通常,为了避免冲突,建议都使用动态链接运行时库(/MD或/MDd),因为这样多个库可以共享同一个C运行时库,减少冲突。3.检查Haru库是否提供了不同运行时库的版本。如果没有,可能需要自己使用与项目相同的设置重新编译Haru库。4.如果项目中还有其他库,也要确保它们使用相同的运行时库设置。5.另外,LNK2005错误也可能是因为符号被多次定义。检查是否重复链接了同一个库(例如,同时链接了Haru库的静态库和动态导入库),或者在不同的库中定义了相同的函数。根据以上思路,我们给出具体的解决步骤:###解决步骤1.**确认Haru库的构建配置**:-如果Haru库是下载的预编译版本,查看其文档或提供的版本信息,确认它是用哪种运行时库(/MT,/MTd,/MD,/MDd)编译的。-如果Haru库是开源的,并且提供了源代码,建议自己使用与项目相同的运行时库设置重新编译Haru库。2.**统一项目的运行时库设置**:-打开MFC项目的属性页。-在Debug配置下,将运行时库设置为与Haru库Debug版本相同的设置(通常,如果Haru库是Debug版本,建议设置为`/MDd`)。-在Release配置下,设置为`/MD`。-如果Haru库是静态链接(/MT或/MTd),那么项目也要使用对应的静态链接(但注意,MFC项目通常使用动态链接MFC,所以可能还需要调整MFC库的使用方式)。3.**重新编译Haru库(如果需要)**:-如果Haru库的预编译版本与项目设置不匹配,需要从源代码编译Haru库。-在Haru库的解决方案中,修改项目属性,将运行时库设置成与你的MFC项目一致。-然后编译得到新的Haru库,再将其链接到你的项目中。4.**检查库的重复链接**:-在项目属性->链接器->输入中,检查是否有重复的库(例如,同时链接了多个不同版本的Haru库)或者冲突的库(如同时链接了静态和动态版本的运行时库)。5.**清理并重新生成**:-清理解决方案,然后重新生成。###注意事项-由于Haru库最新版完全重写了代码,并且舍弃了旧版本的API兼容性,因此确保使用的是新版本的API。-在MFC项目中,如果使用了动态链接MFC,则运行时库通常使用动态链接(/MD或/MDd)以避免冲突。通过以上步骤,通常可以解决LNK2005链接错误。如果问题仍然存在,需要检查具体的错误信息,看是否还有其他冲突的库。§§相关问题§§1.如何在VisualStudio中修改运行时库设置?2.如何从源代码编译Haru库并配置使其适用于MFC项目?3.如何解决MFC项目中多个库之间的运行时库冲突?</think> ### 解决MFC项目中调用Haru库的LNK2005链接错误 #### 错误分析 LNK2005错误通常发生在库冲突时,尤其是当项目同时链接了不同版本的C运行时库(CRT)。在您的案例中: ``` LNK2005: _malloc 已在 libcmtd.lib(dbgheap.obj)MSVCRTD.lib 中定义 ``` 这表示项目同时链接了: 1. **静态调试版CRT**(`libcmtd.lib`) 2. **动态调试版CRT**(`MSVCRTD.lib`) Haru库的最新版完全重写了代码(舍弃了旧API兼容性)并优化了性能[^1],但其编译设置可能与MFC项目的CRT配置冲突。 --- ### 解决方案(逐步操作) #### 1. 统一CRT库版本(关键步骤) 在**项目属性 → C/C++ → 代码生成**中设置: | 配置类型 | 设置项 | 推荐值 | |---------|--------|-------| | **Debug** | 运行时库 | `/MDd`(动态调试DLL) | | **Release** | 运行时库 | `/MD`(动态发布DLL) | ! 同时确保**所有依赖库**(包括Haru)使用相同的设置重新编译 --- #### 2. 检查库链接顺序 在**链接器 → 输入 → 附加依赖项**中: ``` MSVCRTD.lib; # CRT库在前 libhpdfd.lib; # Haru库在后 ``` --- #### 3. 强制符号单一定义 在**链接器 → 命令行**添加: ```bash /FORCE:MULTIPLE /NODEFAULTLIB:libcmt.lib ``` --- #### 4. 清理冲突的库引用 检查是否有以下情况: - 项目手动添加了`libcmtd.lib` - Haru库编译时使用了`/MTd`(静态链接) - MFC项目其他第三方库使用了静态CRT --- #### 5. 重建Haru库(如果上述无效) 从源码编译Haru: ```cmake cmake -DCMAKE_MSVC_RUNTIME_LIBRARY="/MDd" .. ``` 确保编译时添加:`-DHPDF_SHARED_LIB=ON`(生成动态库) --- ### 验证流程 1. 清理解决方案 → 重新生成 2. 检查链接器输出是否只出现`MSVCRTD.lib`或`libcmtd.lib`之一 3. 运行时测试PDF生成功能(验证TrueType字体嵌入是否正常)[^1] > ⚠️ 注意:Haru最新版放弃旧API兼容性[^1],请确认代码使用新版API
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值