MFC 错误 440 error LNK2005: "void * hEvent_Cconn" (?hEvent_Cconn@@3PEAXEA) 已经在 CSProtocal.obj 中定义

本文详细解析了在MFC编程中遇到的errorLNK2005错误,即“void*hEvent_Cconn”重复定义的问题。作者在globalval.h中声明了hEvent_Cconn,但未在对应的globalval.cpp中定义,导致链接错误。文章强调了在.h文件中声明而在.cpp文件中定义的重要性,并解释了两者的区别。

现象:
今天在使用MFC进行编程时,出了一个错误:
错误 440 error LNK2005: “void * hEvent_Cconn” (?hEvent_Cconn@@3PEAXEA) 已经在 CSProtocal.obj 中定义

原因:
没有在声明hEvent_Cconn对应的头文件对应的源文件中进行定义。
我的是在globalval.h中进行的声明 extern HANDLE hEvent_Cconn;//创建客户端连接句柄
在这里插入图片描述
因此需要在globalval.cpp中进行定义 HANDLE hEvent_Cconn;//创建客户端连接句柄
在这里插入图片描述
.h文件和.cpp文件的区别

在h文件中声明(Declare),而在cpp文件中定义(Define)。

h文件中包含声明、条件预编译指令以及类的定义
cpp文件中进行全局变量的定义(及初始化)、全局函数的定义、类函数成员的定义、类带static限定符的数据成员的初始化

作者:GL3_24
来源:优快云
著作权归作者所有。转载请联系作者获得授权。

1>libqrencode.lib(qrencode.obj) : 找到 MSIL .netmodule 或使用 /GL 编译的模块;正在使用 /LTCG 重新启动链接;将 /LTCG 添加到链接命令行以改进链接器性能 1>DrawModeCheckDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall DrawModeCheckDialog::metaObject(void)const " (?metaObject@DrawModeCheckDialog@@UBEPBUQMetaObject@@XZ) 1>DrawModeCheckDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall DrawModeCheckDialog::qt_metacast(char const *)" (?qt_metacast@DrawModeCheckDialog@@UAEPAXPBD@Z) 1>DrawModeCheckDialog.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall DrawModeCheckDialog::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@DrawModeCheckDialog@@UAEHW4Call@QMetaObject@@HPAPAX@Z) 1>NCApplication.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall NCApplication::metaObject(void)const " (?metaObject@NCApplication@@UBEPBUQMetaObject@@XZ) 1>NCApplication.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall NCApplication::qt_metacast(char const *)" (?qt_metacast@NCApplication@@UAEPAXPBD@Z) 1>NCApplication.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall NCApplication::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@NCApplication@@UAEHW4Call@QMetaObject@@HPAPAX@Z) 1>NCApplication.obj : error LNK2001: 无法解析的外部符号 "public: static struct QMetaObject const NCApplication::staticMetaObject" (?staticMetaObject@NCApplication@@2UQMetaObject@@B) 1>sliderStepButton.obj : error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall sliderStepButton::metaObject(void)const " (?metaObject@sliderStepButton@@UBEPBUQMetaObject@@XZ) 1>sliderStepButton.obj : error LNK2001: 无法解析的外部符号 "public: virtual void * __thiscall sliderStepButton::qt_metacast(char const *)" (?qt_metacast@sliderStepButton@@UAEPAXPBD@Z) 1>sliderStepButton.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __thiscall sliderStepButton::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@sliderStepButton@@UAEHW4Call@QMetaObject@@HPAPAX@Z) 1>E:\lyf-Qt\laser\QtVisionLaser\Win32\Debug\\LaserVision.exe : fatal error LNK1120: 10 个无法解析的外部命令 怎么查看哪些头文件需要手动编译
最新发布
06-22
<think>我们正在处理一个Qt项目中的链接错误,具体是LNK2001和LNK1120错误。根据引用,这些错误通常与Qt的元对象系统(moc)有关。moc是Qt用来处理信号和槽机制以及元对象系统的预处理器。如果某个类使用了Q_OBJECT宏,但没有被moc处理,就会导致这些链接错误。###解决步骤1.**检查类声明**:-确保所有使用信号和槽或元对象特性(如Q_PROPERTY)的类都满足以下条件:-继承自QObject(直接或间接)。-在类的私有部分声明了Q_OBJECT宏。-例如:```cppclassMyClass:publicQObject{Q_OBJECTpublic://...};```2.**检查头文件是否被moc处理**:-在Qt项目中,包含Q_OBJECT宏的头文件必须由moc工具预处理,生成一个`moc_*.cpp`文件,然后这个文件会被编译并链接到项目中。-在VisualStudio中使用Qt插件时,通常会自动识别需要moc的头文件。但有时自动配置可能失败。3.**手动设置头文件的项类型**:-在VisualStudio中,右键点击头文件->属性->配置属性->常规->项类型。-需要moc的头文件应该设置为**QtMeta-ObjectCompiler(moc)**。如果被错误地设置为“C/C++标头”,则不会生成moc文件,从而导致链接错误。-按照引用[2]的方法,将出问题的头文件的项类型改为“QtMeta-ObjectCompiler(moc)”。4.**清理和重新生成**:-有时,清理项目并重新生成可以解决问题。具体步骤:-清理项目(生成->清理解决方案)。-删除中间文件(如Debug或Release目录下的`.obj`文件和`moc_*.cpp`文件)。-重新生成项目。-如果问题依旧,尝试引用[3]的方法:备份出错类的头文件和源文件,从项目中移除,然后重新添加并设置正确的项类型。5.**检查项目配置**:-确保Qt模块被正确引入。检查项目的.pro文件(如果使用qmake)或CMakeLists.txt(如果使用CMake)是否包含了必要的模块(如core、gui、widgets等)。-在VisualStudio中,检查项目属性中Qt的配置路径是否正确。6.**查看构建输出**:-在构建过程中,观察输出窗口,看是否有生成`moc_*.cpp`文件的记录。如果没有,说明moc没有运行。###如何定位需要手动编译的头文件?-在项目中,任何包含Q_OBJECT宏且不是由其他头文件包含(即独立存在)的头文件都需要被moc处理。-在VisualStudio中,可以通过以下方式检查:1.打开解决方案资源管理器。2.查看每个头文件的属性,确认其项类型是否为“QtMeta-ObjectCompiler(moc)”。3.如果某个头文件包含Q_OBJECT宏但项类型不是moc,则需要修改。###示例错误分析根据引用[4]的错误信息:```LogonDialog.obj:errorLNK2001:无法解析的外部符号&quot;public:virtualstructQMetaObjectconst*__cdeclQtLogonDlg::metaObject(void)const&quot;```这表明`QtLogonDlg`类的元对象相关函数没有实现,即`moc_QtLogonDlg.cpp`文件没有参与编译。因此,我们需要检查`QtLogonDlg`的头文件(比如`logondialog.h`)是否被正确设置为moc类型。###总结1.确认所有使用Q_OBJECT的类都正确声明。2.在VisualStudio中,将这些类的头文件属性设置为“QtMeta-ObjectCompiler(moc)”。3.清理并重新生成项目。如果以上步骤不能解决,可能需要检查Qt安装和项目配置是否正确。###相关问题1.如何避免Qt项目中的moc相关链接错误?2.在Qt中,信号和槽机制的工作原理是什么?3.除了设置头文件项类型,还有哪些方法可以解决Qt在VS中的链接错误?</think>### 解决 Qt 项目中的 LNK2001 和 LNK1120 错误 #### 错误原因分析 这些链接错误通常由 **元对象编译器(moc)未正确处理头文件** 导致。当类使用 Qt 的元对象系统(如信号槽、Q_OBJECT 宏)但未生成 `moc_*.cpp` 文件时,会出现无法解析的符号错误[^2][^4]。 --- #### 定位和解决步骤 ##### 1. **识别需要 moc 处理的头文件** - **检查标准**:任何包含以下内容的头文件都需要 moc 处理: - `Q_OBJECT` 宏 - 信号/槽声明 - `Q_ENUM`/`Q_PROPERTY` - **手动检查**: ```cpp // 示例:需要 moc 的头文件 class MyClass : public QObject { Q_OBJECT // ← 关键标识 public slots: void mySlot(); }; ``` ##### 2. **在 Visual Studio 中配置头文件** - **关键操作**: 1. 在解决方案资源管理器中右键点击头文件 2. 选择 **属性 → 常规 → 项类型** 3. 设置为 **`Qt Meta-Object Compiler (moc)`** ![属性设置示意图](https://doc.qt.io/qt-6/images/vs-item-type.png) *(图示:VS 中的头文件项类型设置)* - **重要提示**: 若头文件被误设为 `C/C++ 标头`,moc 将不会生成必要的元对象代码[^2]。 ##### 3. **验证 moc 输出** - 编译后检查输出目录(如 `Debug/moc_` 或 `Release/moc_`): - 应存在对应的 `moc_文件名.cpp` 文件 - 若缺失,表明配置未生效 - **错误示例**: `LNK2001: 无法解析的外部符号 &quot;public: virtual struct QMetaObject const * __cdecl MyClass::metaObject(...)` 表明 `MyClass.h` 的 moc 未运行[^4]。 ##### 4. **强制重新生成 moc 文件** - **方法 1**(推荐): - 清理项目 → 删除 `build` 目录 → 重新生成 - **方法 2**(备用): 1. 备份问题头文件(如 `MyClass.h`) 2. 从项目中移除该文件 3. 重新添加文件并设置正确项类型 4. 重新编译(此操作会触发 moc 重新处理)[^1][^3] ##### 5. **检查继承关系** - 确保使用 `Q_OBJECT` 的类**直接或间接继承 `QObject`**: ```cpp // 正确示例 class MyWidget : public QWidget { // QWidget 继承 QObject Q_OBJECT // ... }; ``` --- #### 预防措施 1. **项类型自动化**: - 使用 `.pri` 文件管理头文件类型(Qt 项目最佳实践) 2. **编译前检查**: - 在预构建事件中添加 moc 验证脚本 3. **项目清理**: - 定期执行 **`qmake -nocache &amp;&amp; make clean`**(qmake 项目) > **关键原理**:Qt 的元对象系统(信号槽、反射等)依赖 moc 生成的代码。当链接器报告 `QMetaObject` 相关错误时,90% 的原因是头文件未被正确识别为 moc 输入[^2][^4]。 --- #### 相关问题 1. 如何验证 Qt 项目中的头文件是否已正确配置 moc 处理? 2. 除了项类型设置,还有哪些方法可以解决 Qt 信号槽链接错误3. 当 Qt 项目从 qmake 迁移到 CMake 时,如何处理 moc 配置差异?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值