关于VS “error LNK2005: 已经在 .obj 中定义“
1>OpenCVFi.obj : error LNK2005: "class cv::Point_<double> __cdecl reverse(class cv::Point_<double> const &)" (?reverse@@YA?AV?$Point_@N@cv@@ABV12@@Z) 已经在 HalconFi.obj 中定义
背景:
项目架构为,主程序A,dll库B,dll库中引用了另外一个dll库C,BC都引用了openCV库,单独编译为添加引用c的b没问题,编译c也测试正常,将c添加到b后编译出错,报错如题所示。
查询发现问题原因应该是这个:https://blog.csdn.net/zhaoyong26/article/details/84635383
但是用了网上的#pragma once,#ifndef,extern都没能解决
经过仔细看代码发现,我的情况是这样的一个全局变量在一个头文件中定义,比如:C.h中定义了全局变量int a = 10;
在一个类的头文件B.h中引用头文件C.h如:include "C.h"
此时就会报题目中的错误。
解决办法:
将include "C.h"从B.h中移到了B.cpp中.
分析:
头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量,C++不允许多次定义变量,一个程序中对指定变量的定义只有一次,声明可以无数次。
注意头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量,C++不允许多次定义变量,一个程序中对指定变量的定义只有一次,声明可以无数次。
不过有三个例外,以下三种实体的定义也可放到头文件中。
1.值在编译时就已知的const 变量的定义可以放到头文件中
如:const int num(10);
2.类的定义可以放到头文件中
3.inline 函数
这三个实体可以定义在多个源文件中,只要在每个源文件中的定义相同。
只要两个或者以上的.cpp同时包含了一个定义了变量的.h文件,就会提示错误.
不过注意, 这中间可能会包含些比较复杂的逻辑关系..
例如我的那坨代码..
假定一个定义了变量的1.h文件
有1.cpp和2.cpp, 1.cpp包含1.h, 2.cpp只包含2.h 但是2.h包含了1.h.. 所以1.h中定义的变量编译的时候会在2.pp中有定义. 于是乎2.cpp翻译成的obj里也会有定义, 结果导致提示obj里重定义.
在头文件和cpp文件错中复杂的情况下, 根本就很难判断其祸根源.
所以得出结论:
没事就别在.h中定义变量,或者初始化静态成员变量(我就是后一种情况).
参考文献:
https://blog.csdn.net/zhaoyong26/article/details/84635383
https://blog.csdn.net/jiangge123456/article/details/20865371
另外整理一个完整的,调整了原版格式,贴在下面,大家一起探讨~
出现上面的错误,只要原因有如下几个:
1.头文件的重复包含
包含的头文件中含有变量、函数、类的定义,在其他使用的地方多次包含,造成重复包含,产生LNK2005错误,
有两种解决方法:
1)使用宏 在头文件head.h中加入
#ifndef HEAD_H_ //这个地方写法有不少#define HEAD_H_......#endif
2)使用预编译,文件开头加入
#pragma once
2. 使用第三方库造成
主要情形是C运行期函数库和MFC的库冲突造成的。具体的方法就是将提示出错的库放到另一个库的前面。
举例:
#include <WinSock2.h> //WinSock2.h头文件必须在Windows.h之前 #include <Windows.h>
3. 重复定义全局变量
全局变量是针对整个工程的,在一个CPP文件的定义:int nCount;那么在使用的CPP文件中就应该使用extern int nCount即可,如果还是使用int nCount 就会产生LNK2005错误;
根据C++标准的规定,一个变量是声明,必须同时满足两个条件,否则就是定义:
1)使用extern 关键字 2)不能给变量赋初值
如果还是报错的话,只在头文件中声明函数,把函数定义都放到cpp文件中。这里面转自https://blog.csdn.net/wanzew/article/details/81638128出现的问题:
这里我有三个源文件:Base.hpp, Base.cpp 和 main.cpp
在Base.hpp里面定义一个基类,注意,基类只包含构造函数和析构函数的声明,函数在Base.cpp里实现。
此外在Base.hpp中还有一个函数的定义(函数声明和定义都在Base.hpp文件中)三个文件代码如下:
// Base.hpp #ifndef VIRTUAL_H #define VIRTUAL_H#include<iostream> #include<string>using namespace std;class Base{ public:Base();~Base();private:char *p; };void platform(Base *pBase){cout << "this is just a function..." << endl; }#endif//Base.cpp #include"Base.hpp"Base::Base(){cout << "construction function..." << endl; }Base::~Base(){cout << "destructor function..." << endl;delete p; }//main.cpp #include"Base.hpp" #include<iostream> using namespace std;int main(){cout << "main..." << endl;Base * pBase = new Base;delete pBase;system("pause");return 0; }
此时编译会出现一个问题:
1>Base.obj : error LNK2005: "void __cdecl platform(class Base *)" (?platform@@YAXPAVBase@@@Z) 已经在 main.obj 中定义
1>c:\users\wanzew\documents\visual studio 2013\Projects\Class\Debug\Class.exe : fatal error LNK1169: 找到一个或多个多重定义的符号
经过分析,确定了这是由于两个实现文件(main.cpp 和 base.cpp)中重复包含了头文件#include<base.hpp>而造成的。
要注意的是,在这里,在头文件中加入#ifndef……#endif这样的预编译命令是没用的,因为这是防止嵌套包含头文件的,而本例中并没有嵌套包含,是 在两个文件中分别包含。只在头文件中声明函数,把函数定义都放到cpp文件中,本例中把platform函数的定义从Base.hpp文件中移到Base.cpp文件中。
————————————————
版权声明:本文为CSDN博主「Wzning0421」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hanzhen7541/article/details/99681461
其他人的解决方案:
https://social.msdn.microsoft.com/Forums/en-US/2f1a7c23-5981-4526-9b4b-b1322e838716/error-lnk2005-quotvoid-cdecl-bp5voidquot-bp5yaxxz-already-defined-in-testobj?forum=vclanguage
Let's detail a bit:
testDoc.h includes mytest.h
testDoc.h is included by testDoc.cpp and testView.cpp
So once the function bp5 will be compiled in testDoc.obj and once in testView.obj. The #pragma once prevents the header file to be included many times in the same .cpp file not in different cpp files.
You have 2 solutions for this:
1. make the function inline:
inline void bp5() {
int a = 0;
a += 1;
}
2.
put the function in a cpp file and in the header add only:
void bp5();
var code = "bd9610e7-2f2a-4dd0-ab70-a414052825b5"
关于VS “error LNK2005: 已经在 .obj 中定义“相关推荐
- C++中的“error:LNK2005 已经在*.obj中定义”异常
C++中的"error:LNK2005 已经在*.obj中定义"异常问题 异常现象如下: C++中的"error:LNK2005 已经在*.obj中定义" ...
- C++ error:LNK2005 已经在*.obj中定义
一.错误 LNK2005 "int __cdecl test01(void)" (?test01@@YAHXZ) 已经在 ShellExecuteTest.obj 中定义 Test ...
- error LNK2005 已经在***.obj中定义
编程中经常能遇到LNK2005错误--重复定义错误,其实LNK2005错误并不是一个很难解决的错误.弄清楚它形成的原因,就可以轻松解决它了. 造成LNK2005错误主要有以下几种情况: ...
- error:LNK2005 已经在*.obj中定义的一种情况及解决办法
我的代码发生了这个错误,但是用了网上的#pragma once,#ifndef,extern都没能解决 经过仔细看代码发现,我的情况是这样的一个全局变量在一个头文件中定义,比如:head1.h中定义了 ...
- error:lnk2005 已经在*.obj中定义_如何在 Spring 中自定义 scope
大家对于 Spring 的 scope 应该都不会默认.所谓 scope,字面理解就是"作用域"."范围",如果一个 bean 的 scope 配置为 sing ...
- vs报错 已经在 helpers.obj 中定义
已经在 helpers.obj 中定义 1>正在生成代码... 1>localizer.obj : error LNK2005: "class std::vector<cl ...
- ZZmsvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义
FROM: http://blog.csdn.net/sptoor/article/details/6203376 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) ...
- error LNK2005: “找到一个或多个多重定义的符号” 已经在 xxxx.obj 中定义 的解决方法
error LNK2005: "找到一个或多个多重定义的符号" 已经在 xxxx.obj 中定义 的解决方法 参考文章: (1)error LNK2005: "找到一个或 ...
- msvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义
转载 很需要补充的知识. 可惜网络阅读一直不是强项. 目前实在有点看不进去. 先保存下来吧... 牛到连评论都是贼深奥滴! 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Libra ...
最新文章
- PhotoshopCS6-视觉特效插画技法-1-什么是视觉特效(1)
- tensorflow 进阶 五 ---TensorFlow conv2d原理及实践
- HTML5学习笔记(三):HTML5的智能提示在VisualStudio2010
- Oracle创建pfile spfile 文件及其恢复
- java日志之slf4j与logback简单使用
- Linux中断不能进行任务调度,关中断是否禁止任务调度?关中断能作为互斥吗?...
- 汉字笔顺口诀_一帮40后理工男编出新型字典,《笔顺码字典》在汉首发
- 数学建模国二难不难_【干货】同学听说你想了解数学竞赛和数学建模?文末微积分串讲来袭,拯救你的期中!...
- libiconv android编译,linux环境下libiconv库基于Android NDK的编译方法
- 马哥python课堂笔记_马哥教育PYTHON相关基础 笔记
- openjudge666:放苹果
- [Python从零到壹] 五十四.图像增强及运算篇之局部直方图均衡化和自动色彩均衡化处理
- matlab 声源定位csdn_麦克风阵列声源定位 GCC-PHAT(一)
- 当Proteus 8 Professional运行程序的时候出现有些器件不可用
- 5G网络逐渐普及TSINGSEE青犀视频云边端架构网页视频实时互动直播系统又将如何发展?
- 毕业设计-基于微信小程序的答题系统
- android通过代码设置铃声_使用VS Code调试Android C_C++代码(无需Android源码)
- MySQL测试题——开发公司人事管理系统,包括 Employee表 和 Department表
- 常见的股东纠纷案例类型及处理方法汇总
- md/markdown转html在线工具
热门文章
- html中文本信息导出表格中,了解如何使用表格在网站中显示内容
- 擅自修改金蝶k 3服务器密码,金蝶k3登陆常见问题.docx
- Android Camera(一):camera模组CMM介绍
- freemarker转PDF,支持分页,增加页眉页脚
- 通过JS修改select默认选中值触发onchage事件
- 基于DSP+FPGA高速运动控制器设计
- MySQL数据库快速入门到精通(超详细保姆级,建议收藏)这可能是目前最适合你的教程,从基础语法到实例演示。
- mysql测试数据库 jmeter_第三篇--Jmeter测试数据库Mysql
- 运维监控软件zabbix 5.0教程(一):安装及配置
- PCL点云边界特征检测 (附完整代码 C++)