C++编译链接错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++编译链接错误相关的知识,希望对你有一定的参考价值。

头文件:
#pragma once
#include "cocos2d.h"
using namespace cocos2d;
class GameInstance

public:
static GameInstance* getInstance();
private:
static GameInstance* g_Instance;
GameInstance(void);
~GameInstance(void);
CC_SYNTHESIZE(Vector<Node*>, epath, EnermyPath);
;

源文件:
#include "GameInstance.h"
GameInstance::GameInstance()
GameInstance::~GameInstance()

delete g_Instance;

GameInstance* GameInstance::getInstance()

if (g_Instance == NULL)

g_Instance = new GameInstance();

return g_Instance;


编译有错:错误 28 error LNK2001: 无法解析的外部符号 "private: static class GameInstance * GameInstance::g_Instance" (?g_Instance@GameInstance@@0PAV1@A) E:\GDocument\GameTest\proj.win32\GameInstance.obj

C++常见编译/链接错误及其解决办法

1. 解决error LNK2005: ___crtExitProcess 已经在 LIBCMTD.lib(crt0dat.obj) 中定义
有的时候, 在 Debug 模式下编译没问题, 换到 Release 模式就发生一堆问题.
典型的例子, 就是因为 c++ runtime library 设定不同, 所造成的重复定义连结错误.
而另一个常见的例子是 专案与 library 使用不同的字元集合设定
(如: 一个用 Unicode Character Set, 另一个用 Multi-Byte Character Set)
这个错误发生原因, 有可能是
1. 你 link 的 lib 使用 C++ Multi-threaded DLL (/MD)
2. 而你的 source 使用的 C++ runtime library 是 Multi-threaded (/MT)
导致重复定义
解决方法:
两个使用相同的 C++ runtime library.例如都使用 static 的 Multi-threaded (/MT).
2. 错误 1error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) 已经在 LIBCMT.lib(typinfo.obj) 中定义 MSVCRTD.lib
项目 -> 属性 -> c/C++ -> 代码生成 -> 运行时库 设置为: 多线程调试 DLL (/MDd)
被引用的库和调用的程序编译选项不同,需要改成一致后编译
3.#pragma once与 #ifndef的区别
为了避免同一个文件被include多次
1 #ifndef方式
2 #pragma once方式
在能够支持这两种方式的编译器上,二者并没有太大的区别,但是两者仍然还是有一些细微的区别。
方式一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
... ... // 一些声明语句
#endif
方式二:
#pragma once
... ... // 一些声明语句
#ifndef的方式依赖于宏名字不能冲突,这不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件不会被不小心同时包含。当然,缺点就是如果不同头文件的宏名不小心“撞车”,可能就会导致头文件明明存在,编译器却硬说找不到声明的状况
#pragma once则由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。带来的好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,重复包含更容易被发现并修正。
方式一由语言支持所以移植性好,方式二 可以避免名字冲突
4.error LNK2019: 无法解析的外部符号 __imp__PathCombineW
PathCombine是Shell api 需要引入库#pragma comment( lib, "shlwapi.lib")
5.error C2662: "MyClass::GetName()”: 不能将“this”指针从“const MyClass”转换为“MyClass &”
bool MyClass::operator==(const MyClass* n1) const
return GetName() == n1->GetName();
原因是不能在const函数中调用对象的非const方法,MyClass中的GetName()必须是const的。
6.template 模板
模板声明和定义必须在同一个文件中,而且只有实例话模板类型时才编译模板实例
7.error C2275: “MyClass”: 将此类型用作表达式非法 MyClass.Instance();
原因:Instance是静态方法,用.引用会出错。应该是MyClass::Instance()
8.error LNK2019: 无法解析的外部符号 "public: __thiscall MyClass(void)
原因:只声明了构造函数,MyClass(); ,但未定义。 可以定义空函数,或者直接注释掉,使用默认构造函数。
9.error C2504: “testing”: 未定义基类
class PackToolTest : testing.Test
原因:Test是testing命名空间下的一个类,需要用域操作符,testing::Test
还有一个问题,缺少基类继承权限(public、protected、private)
10.error C2864: “MyClass::_nullpack”: 只有静态常量整型数据成员才可以在类中初始化
class MyClass string _nullpack = "test";
原因:c++ 中,成员变量不能在声明时初始化,而是在构造函数初始化列表中先初始化
11.error LNK2019: 无法解析的外部符号_WinMain@16int main()
原因:由于创建的是Win32 Project,和Win32 console Project的链接库不同
方法1:在程序最开始的地方加上以下语句
#pragma comment(linker, "/subsystem:console ")
方法2:project > > setting > > 在link 的project options 中将/subsystem:windows(console)删了
12.类似“已经在 msvcprtd.lib(MSVCP80D.dll) 中定义”问题
vs2005 Debug /Release需要分别配制
分析一下错误来源,会发现:
1. 错误来源主要是重复定义的问题,而且重复定义的基本上都是VC Runtime和Standard C++ Library中的函数
2. LIBCMT和LIBCPMT为Release下的Lib,本来不应该出现在Debug版本的链接的Lib中
3. 重复定义的问题主要出现在:LIBCMT, LIBCPMT, MSVCPRTD, MSVCRTD
来看看出问题的LIB是那些:
1. LIBCMT:C Runtime库的多线程静态链接的Release版本
2. LIBCPMT:C++ Standard Library的多线程静态链接的Release版本
3. MSVCPRTD:C++ Standard Library的多线程DLL的Debug版本
4. MSVCRTD:C Runtime Library的多线程DLL的Debug版本
当 前我们的配置是多线程DLL的Debug版,因此3和4是应该出现在link的列表中的,不属于多余。而后两者则是只是当多线程静态链接Release版 中才会出现。这提示我在项目中加入的ANTLR.LIB可能是造成这个问题的根源,因为静态库的编译选项很容易和主程序发生冲突,并且根据实际信息我们可 以看出ANTLR.LIB应该是用多线程静态链接的Release版本来编译的。
解决方法:
1、首先查看编译项目依赖的其他项目的运行时库是否一致
2、如果不一致,改为同样的运行时库,如在下编译的是:“多线程调试 DLL (/MDd)”,现在需要把所有的依赖项目的运行时库都改为一致的库,就OK了。
13.error C2143: 语法错误 : 缺少“;”(在“*”的前面)
原因:产生错误处,某类型未include,可能头文件名拼写错误、头文件名已更改
14.error C2572: “MyClass::Invoke”: 重定义默认参数 : 参数 2
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type = ASYN)
原因:默认参数,只需在声明时指定。方法定义的时候无需指定默认参数。
string MyClass::Invoke(const CParam& paraObj, INVOKETYPE type )
...
15.错误 C2558 没有可用的复制构造函数或复制构造函数声明为“explicit”
试图复制其复制构造函数为 private 的类。在大多数情况下,不应复制具有 private 复制构造函数的类。通用编程技术声明 private 复制构造函数以防止直接使用类。该类本身可能无用,或需要另一个类才能正常工作。
尝试复制其复制构造函数为 explicit 的类。用 explicit 声明复制构造函数会阻止将类的对象传递到函数或从函数返回类的对象。
原因: 拷贝构造函数、赋值函数参数必须用const修饰
16.不能创建抽象类对象
原因: 1. 存在虚函数未实现; 2. 由于疏忽重载虚函数格式错误(此问题需要仔细检查才能发现); 3. 虚函数名称与系统中已有的虚函数重名,导致重载失败(这点很纳闷)。
17.没有找到MSCRV80D.dll
工程属性: 配置类型 由 exe 改成 lib 后生成, 然后再改回来,运行时会出现 “没有找到MSCRV80D.dll” 的异常
解决方法:
工程属性:MFC的使用 由 “使用标准Windows库” 改成 “在静态库中使用MFC“ 生成 ,然后再改回来,生成、运行 OK
18.CVTRES : fatal error CVT1100: 重复的资源。type:MANIFEST, name:1, language:0x0409
另一个则提示为:
LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
已经到了链接期,应该说,问题就不像编译通不过那么别扭了,而查阅MSDN关于这两个问题的说明,终于找到了解决的方法,现简单的陈述如下:
首先,出现这两个问题的原因都是一个,即文件中的现有资源文件和新资源字符串表 ID 冲突。微软也给出了解决这个问题的方法,但是,在现有的情况下,这个方法是靠不住的,因为,不可能不使用wx.rc资源。所以,一个变通的解决方法就是:
工程属性->配置属性-> 清单工具->输入和输出->嵌入清单,选择[否],即可。
参考技术A 静态成员变量g_Instance没有初始化 参考技术B 具体一点错误。可能是链接库没找到。
请采纳。

Borland C++ builder 6 链接器错误

【中文标题】Borland C++ builder 6 链接器错误【英文标题】:Borland C++ builder 6 linker error 【发布时间】:2010-02-05 06:06:59 【问题描述】:

我正在使用 Borland C++ Builder 6 重新编译一个项目。由于链接器错误,重新编译过程失败。消息是:

“[链接器致命错误] 致命无法打开文件 ABCC.lib”

我删除了项目选项和环境选项中对ABCC.lib的所有引用,但仍然出现同样的错误。我什至尝试从 .bpr 文件中手动删除 ABCC.lib,但错误并没有消失。

另外,什么是 ABCC.lib?

感谢任何帮助。

提前致谢。

大卫。

【问题讨论】:

【参考方案1】:

您是否尝试在标题/源代码中查找可能需要此库的#pragma 链接或#pragma 注释行?

【讨论】:

以上是关于C++编译链接错误的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio opencv C++ 在运行时编译链接库错误

由于C++类库版本不同导致的OpenCV编译链接错误

Borland C++ builder 6 链接器错误

错误:链接:致命错误 LNK1561:入口点必须定义 C++

重复符号链接器错误(C++ 帮助)

Visual Studios 2012 更改运行时库会导致链接错误,使用 C++