cmake:解决error LNK2005: void * __cdecl operator new(unsigned __int64) already defined in LIBCMTD.lib

本文详细解析了在使用/MT选项编译MFC项目时遇到的链接错误原因,涉及CRT库与MFC库的new/delete函数冲突。提供三种解决方案:调整链接顺序、使用/FORCE选项及优化CMake脚本。

当以/MT选项编译MFC项目时,会报下面的错误

1>nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z) 已经在 LIBCMTD.lib(new_scalar.obj) 中定义
1>nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPEAX@Z) 已经在 LIBCMTD.lib(delete_scalar.obj) 中定义
1>nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned __int64)" (??_U@YAPEAX_K@Z) 已经在 LIBCMTD.lib(new_array.obj) 中定义
1>nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPEAX@Z) 已经在 LIBCMTD.lib(delete_array.obj) 中定义
1>J:\gfirfid\project.vs\bin\Debug\Ast2600FaceSample.exe : fatal error LNK1169: 找到一个或多个多重定义的符号

关于为什么会报这个错误,还是要看microsoft官方的说明:
A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++

英文一大堆,其实简要说来就是,CRT库和MFC库都定义了new,delete和 DllMain 函数,这些函数要求先链接 MFC 库,然后再链接 CRT 库。
因为连接顺序不正确造成编译错误。

解决办法–修改连接顺序

如果你是手工创建的MSVC工程,解决办法很简单,网上类似的文章很多,方法都一样,就是修改uafxcwd.lib,libmcmtd.lib的连接顺序,确保uafxcwd.lib在libmcmtd.lib前面。
参见:https://www.cnblogs.com/qingtian224/p/5833456.html

解决办法–/FORCE选项

还有个比较懒的办法,就是用在连接命令中加上/FORCE选项,忽略这个错误
在这里插入图片描述

这样以来上面的连接错误就成警告:

1>LINK : warning LNK4075: 忽略“/INCREMENTAL”(由于“/FORCE”规范)
1>nafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned __int64)" (??2@YAPEAX_K@Z) 已在 LIBCMTD.lib(new_scalar.obj) 中定义;已忽略第二个定义
1>nafxcwd.lib(afxmem.obj) : warning LNK4006: "void __cdecl operator delete(void *)" (??3@YAXPEAX@Z) 已在 LIBCMTD.lib(delete_scalar.obj) 中定义;已忽略第二个定义
1>nafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new[](unsigned __int64)" (??_U@YAPEAX_K@Z) 已在 LIBCMTD.lib(new_array.obj) 中定义;已忽略第二个定义
1>nafxcwd.lib(afxmem.obj) : warning LNK4006: "void __cdecl operator delete[](void *)" (??_V@YAXPEAX@Z) 已在 LIBCMTD.lib(delete_array.obj) 中定义;已忽略第二个定义
1>J:\gfirfid\project.vs\bin\Debug\Ast2600FaceSample.exe : warning LNK4088: 因 /FORCE 选项生成了映像;映像可能不能运行

个人认为这个办法是不可取的,属于掩盖问题,掩耳盗铃。

解决办法–cmake脚本

如果你的项目是cmake脚本创建的,手工修改MSVC的工程配置就不可取了。要从修改cmake脚本下手才能根本解决,不留后患。

	# WITH_STATIC_CRT在这里指定是否开启/MT (静态库连接)选项
	# 根据 WITH_STATIC_CRT 决定是否在_target中定义_AFXDLL宏
	# 这里$<...>用到了生CMAKE成器表达式(cmake-generator-expressions),参见CMAKE官方文档
	target_compile_definitions(${_target} PRIVATE $<$<NOT:$<BOOL:${WITH_STATIC_CRT}>>:_AFXDLL> )
	if(WITH_STATIC_CRT)
		# 定义nafxcw 和libcmt的连接顺序,库名根据$<CONFIG:Debug>表达式决定是否有d后缀
		# Debug版本为 nafxcwd,libcmtd,Release版本为nafxcw,libcmt
		target_link_libraries(${_target} nafxcw$<$<CONFIG:Debug>:d> libcmt$<$<CONFIG:Debug>:d>)
	endif()

代码转载自:https://pan.quark.cn/s/11d565366452 【USB转I2C/IIC适配器上位机应用程序】是一种针对I2C(Inter-Integrated Circuit)通信协议而构建的工具,其通过USB端口将个人计算机转变为能够与I2C设备进行交互的控制器。该适配器使开发人员与工程师能够便捷地对遵循I2C协议的芯片执行读取和写入任务,因此在硬件构建和测试阶段能够显著提升效率,对于核实I2C接口芯片的工作性能具有特别的价值。 I2C协议是由飞利浦(现NXP半导体)于1980年代初创立的一种双线式串行总线,其目的是用于连接微控制器及其他外围设备。该协议仅需两条信号线(SDA - 数据线,SCL - 时钟线)即可完成多设备间的通信,大幅度削减了电路板上的布线需求,从而降低了生产成本。I2C协议提供多种速度等级,涵盖标准模式(100kbps)、快速模式(400kbps)以及高速模式(3.4Mbps),旨在满足不同场景下的应用要求。 Ginkgo USB转I2C适配器是这项技术的具体应用实例,它提供了一个物理接口,用于将USB端口转换为I2C端口。适配器内部装配有一个微控制器单元,该单元负责处理从USB到I2C的信号转换,并且通过USB线路向计算机传输信息,同时接收来自计算机的指令以操控I2C总线。这种设计使用户无需具备深厚的硬件知识,仅需借助上位机软件即可实现对I2C设备的操控。 Ginkgo I2C Adapter Classic是与该适配器相配套的软件,通常包含以下几项核心功能: 1. 设备识别:自动检测并建立与USB转I2C适配器的连接。 2. 总线探查:扫描I2C总线上所连接的设备地址,有助于准确定位设备的位置。 3. 读写指令...
内容概要:本文围绕麦克斯韦旋度方程的差分形式在平面极化磁场中的应用展开深入研究,并通过Matlab代码实现相关数值仿真。研究的核心是将经典的麦克斯韦方程组转化为适用于数值计算的有限差分格式,构建离散化数学模型,进而模拟和分析平面极化条件下磁场的空间分布特征与时间演化规律。文中系统阐述了差分方法的理论基础与数学推导过程,详细说明网格划分、边界条件设定及迭代求解策略,最终利用Matlab编程实现电磁场的可视化仿真,有效验证了差分方法在求解复杂电磁场问题中的准确性与可行性。该研究不仅加深了对电磁波传播机理的理解,也为电磁器件的设计优化与工程仿真提供了可靠的数值分析手段。; 适合人群:具备电磁场与电磁波理论基础,熟悉偏微分方程数值解法,且掌握Matlab编程技能的电气工程、物理学、应用数学等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入掌握麦克斯韦旋度方程的有限差分法基本原理及其在二维平面磁场仿真中的具体实施步骤;②学习如何利用Matlab进行电磁场问题的建模、编程求解与结果可视化;③为后续开展更复杂的电磁兼容、天线设计或光子晶体等领域的数值模拟研究奠定坚实的技术基础。; 阅读建议:建议读者结合经典电磁场理论教材,透彻理解麦克斯韦方程组的物理内涵,然后循序渐进地跟进文中的差分格式推导过程,务必动手复现并调试所提供的Matlab代码,通过调整参数观察仿真结果的变化,从而深刻领悟数值方法的实质与应用技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值