提问人:Novellizator 提问时间:3/29/2012 最后编辑:moffeltjeNovellizator 更新时间:10/11/2022 访问量:705487
对象文件中未解析的外部符号 [重复]
Unresolved external symbol in object files [duplicate]
问:
在Visual Studio中编码期间,我收到一个未解决的外部符号错误 我不知道该怎么办。我不知道怎么了。 你能破译我吗?我应该在哪里查找哪些类型的错误?
1>Form.obj : error LNK2019: unresolved external symbol "public: class Field * __thiscall Field::addField(class Field *)" (?addField@Field@@QAEPAV1@PAV1@@Z) referenced in function "public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Form@@QAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2019: unresolved external symbol "public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Field@@UAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField@@QAE@AAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::prompt(void)" (?prompt@Field@@UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall Field::describe(void)" (?describe@Field@@UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals
答:
检查是否包含所引用的解决方案中的所有源文件。
如果未在项目中包含类的源文件(以及实现),则不会生成该文件,并且无法在编译过程中进行链接。Field
或者,也许您正在使用静态或动态库,并且忘记告诉链接器有关 s?.lib
评论
\
SOURCES += main.cpp \
它看起来缺少一个库或包含,你可以尝试找出你的库的哪个类具有 getName、getType 等......并将其放在头文件中或使用 .#include
此外,如果这些恰好来自外部库,请确保在项目文件中引用它们。例如,如果此类属于 abc.lib,则在 Visual Studio 中
- 单击“项目属性”。
- 转到配置属性、C/C++、 生成,验证是否指向“其他”下的 abc.lib 位置 包括目录。在“链接器”和“输入”下,确保具有 abc.lib 在 Additional Dependencies 下。
此错误通常意味着某些函数具有声明,但没有定义。
例:
// A.hpp
class A
{
public:
void myFunc(); // Function declaration
};
// A.cpp
// Function definition
void A::myFunc()
{
// do stuff
}
在您的情况下,找不到定义。问题可能是你包含一个头文件,它带来了一些函数声明,但你要么:
- 不要在 cpp 文件中定义函数(如果您自己编写了此代码)
- 不要包含包含定义的 lib/dll 文件
一个常见的错误是,您将函数定义为独立函数,而忘记了类选择器,例如,在 .cpp 文件中:A::
错:对: void myFunc() { /* do stuff */ }
void A::myFunc() { /* do stuff */ }
评论
void myFunc() {}
A::void myFunc() {}
我只是很难受。一切都是合乎逻辑的。我声明了一个构造函数,但没有定义它
class SomeClass
{
SomeClass(); // needs the SomeClass::SomeClass(){} function defined somewhere, even here
}
当我忘记如此基本的东西时,我几乎把头撞在键盘上。
很长一段时间以来,我第一次做一些 C++,当我忘记为函数定义添加 ClassName:: 前缀时,我收到此错误,因为这是 C++ 独有的。所以记得也要检查一下!
指针
我遇到了这个问题,并使用指针解决了它。我看到这不是你的问题,但我想我会提到它,因为我当然希望它在我一个小时前看到这个时就在这里。我的问题是在不定义静态成员变量的情况下声明它(定义需要在其他一些设置之后出现),当然指针不需要定义。同样基本的错误:P
评论
除了上面 Chris Morris 的出色回答之外,我还发现了一种非常有趣的方法,如果您调用的虚拟方法尚未设置为纯但未实现自己的实现,则可以收到相同的错误。这是完全相同的原因(编译器找不到该方法的实现,因此是骗子),但我的IDE丝毫没有发现这个错误。
例如,以下代码将收到具有相同错误消息的编译错误:
//code testing an interface
class test
{
void myFunc();
}
//define an interface
class IamInterface
{
virtual void myFunc();
}
//implementation of the interface
class IamConcreteImpl
{
void myFunc()
{
1+1=2;
}
}
但是,将 IamInterface myFunc() 更改为纯虚拟方法(“必须”实现的方法,而不是“可以”覆盖的方法)将消除编译错误。
//define an interface
class IamInterface
{
virtual void myFunc() = 0;
}
希望这对下一个 StackOverFlow 人员逐步执行代码有所帮助!
请参阅 MSDN 上的链接器工具错误LNK2019,其中包含导致LNK2019的常见问题的详细列表。
确保用
#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H
// your header code here
#endif
如果你不这样做,坏事——包括这个——可能会发生
评论
#pragma once
我刚刚看到了我无法从 .cpp 文件中的 main 调用函数的问题,在 .h 文件中正确声明并在 .c 文件中定义。遇到链接器错误。同时,我可以从通常的.c文件中调用函数。可能这取决于调用约定。解决方案是在每个 .h 文件中添加以下 preproc 行:
#ifdef __cplusplus
extern "C"
{
#endif
而这些最终
#ifdef __cplusplus
}
#endif
我相信有关原因和补救措施的大部分要点都已由此线程中的所有贡献者涵盖。我只想指出我的“未解决的外部”问题,它是由定义为宏的数据类型引起的,该数据类型的替换方式与预期不同,这导致向相关函数提供了不正确的类型,并且由于从未定义过具有类型的函数,因此无法解决。特别是,在 C/C++ -> 语言下,有一个名为“将WChar_t视为内置类型”的属性,它应该定义为“否 (/Zc:wchar_t-)”,但在我的情况下没有。
评论
我的问题是 sconsign 没有定义该文件。这可能非常令人困惑,因为 Visual Studio 在项目中具有该文件,但完全正在构建其他内容。cpp
cpp
我的问题是:我必须对 ctor 为“未解析的外部”的类进行转发声明。
在我收到错误的文件中,我必须放置如下内容:
#include "ClassB"
class ClassB; // this solved the problem
class ClassA{
void foo(){
ClassB* tmp = new ClassB();
// ...
}
};
当然,我的项目要复杂得多,这只是一个片段示例。此外,在使用命名空间时,也要声明它们。
有时,如果添加了新的头文件,并且由于此错误开始出现,您还需要添加库才能摆脱。unresolved external symbol
例如:
#include WtsApi32.h
将需要:
#pragma comment(lib, "Wtsapi32.lib")
只是花了几个小时才发现问题是我的主文件有扩展名而不是.c
.cpp
:/
我有相同的链接错误,但来自引用另一个 dll 的测试项目。发现在错误消息中指定的每个函数前面添加后,链接运行良好。_declspec(dllexport)
评论
__declspec
__declspec(dllimport)
此链接器错误的一个可能原因也可能是已声明但未在头文件中定义的函数,该文件随后包含在其他位置。内联函数必须在使用它们的每个翻译单元中定义。inline
我遇到了一个错误,我的项目被编译为 x64 项目。我使用了一个编译为 x86 的库。
我已将库重新编译为 x64 并解决了它。
还有一种检查的可能性,这次是我的问题。
我已将该函数添加到库中,并在搜索路径中包含库的输出文件夹。
但是我还有一个文件夹,里面有之前列出的旧版本的库,所以 VS 使用的是旧库,当然没有找到新功能。
另一个可能的问题(我只是挠了一段时间):
如果将函数定义为 ,则它们(当然!)必须在标头(或内联文件)中定义,而不是在 cpp 中定义。
就我而言,它们位于内联文件中,但只是因为它们是特定于平台的实现,并且 cpp 包含这个相应的 inl 文件......而不是标题。是的,s**t 发生了。inline
我想我也会把它留在这里,也许其他人遇到了同样的问题并在这里找到了它。
确保您没有尝试将插入或提取运算符重载为内联函数。我遇到了这个问题,只有当我删除该关键字时它才会消失。
在我的情况下,是什么导致了它:
我有一个没有 Foo.h 的大文件。 是这样开始的:Foo.cpp
Foo.cpp
// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;
我删除了“static”关键字并添加了一个:Foo.h
extern int var;
你看到错误了吗?
我完全错过了 var 最初是在命名空间中定义的,因为命名空间声明被埋在其他代码中。解决方法是像这样更改 extern:
namespace NS {
extern int var;
}
“未解析的外部符号”错误的可能原因可能是函数调用约定。
确保所有源文件都使用相同的标准(.c 或 .cpp),或指定调用约定。
否则,如果一个文件是 C 文件(source.c),另一个文件是 .cpp 文件,并且它们链接到相同的标头,则将抛出“未解析的外部符号”错误,因为该函数首先定义为 C cdecl 函数,但随后使用相同标头的 C++ 文件将查找 C++ 函数。
为避免“未解析的外部符号错误”,请确保函数调用约定在使用它的文件中保持相同。
评论
我来这里寻找可能的解释,然后仔细查看链接器错误之前的行。事实证明,这是一个额外的可执行文件,缺少全球声明!
我刚刚遇到了同样的错误,我设法通过在头文件中替换为来避免它。;
{}
#ifndef XYZ_h
#define XYZ_h
class XYZ
{
public:
void xyzMethod(){}
}
#endif
当它是它时,它不想编译。void xyzMethod();
此错误可能是由于将模板类的函数定义放在单独的 .cpp 文件中所导致的。对于模板类,必须在头文件中声明成员函数。可以通过在 .h 文件中以内联方式或紧跟在类定义之后定义成员函数来解决此问题。
例如,您可以像这样内联定义函数定义,而不是像其他类那样将函数定义放在 .cpp 文件中:
template<typename T>
MyClassName {
void someFunction() {
// Do something
...
}
void anotherFunction() {
// Do something else
...
}
}
或者,您可以在类定义之后但在同一个文件中定义它们,如下所示:
template<typename T>
MyClassName {
void someFunction();
void anotherFunction();
}
void MyClassName::someFunction() {
// Do something
...
}
void MyClassName::anotherFunction() {
// Do something else
...
}
我只是想分享一下,因为似乎没有人提到模板类。这是我犯错的原因。
评论
就我而言,我需要将函数名称添加到 DEF 文件中。
LIBRARY DEMO
EXPORTS
ExistingFunction @1
MyNewFunction @2
我遇到了一个类似的问题,最终设法通过添加到类的声明中来解决它:__declspec(dllimport)
// A.hpp
class __declspec(dllimport) A
{
public: void myFunc();
// Function declaration
};
就我而言,我的头文件中有多个命名空间而没有嵌套(一个接一个),但是在我的源文件中,我不小心将其中一个命名空间嵌套在另一个命名空间中:
// myExample.h
#ifndef MYEXAMPLE_H
#define MYEXAMPLE_H
namespace A
{
void aFunc();
}
namespace B
{
void bFunc();
}
// myExample.cpp
#include "myExample.h"
namespace A
{
void aFunc()
{
...
}
namespace B // whoops! I nested this inside namespace A when I didn't mean to.
{
void bFunc()
{
...
}
}
}
// main.cpp
#include "myExample.h"
int main()
{
myExample::B::bFunc();
return 0;
}
当我使用 F12 对 Main 中的函数“转到定义”时,Visual Studio 在源文件中找到了代码,即使它是意外地在更深的命名空间中声明的。
调试技术
我在尝试调试问题时重命名函数时发现了这个问题。重命名预览窗口显示了一个“外部引用”节点,其中源文件中的函数意外地嵌套在另一个命名空间下。
我有同样的问题。我的一天在工作,然后在我提取最新代码后的第二天没有工作。
最新的代码不包括我在库中引用的项目。所以当我重建我的库时,它删除了那个 .obj 文件,哎呀......
我重新包含了我需要的项目,构建了我的库,然后重建了我的失败的项目,它运行良好。
故事的寓意是,在深入研究 rabit 漏洞之前,请验证您的 .obj 文件是您引用它的位置。
我的项目中遇到了同样的错误,我已经设法解决了这个问题。
这个问题把我带到了这里,但我发现它是 Visual Studio 本身中的构建文件问题。
如果您找不到代码中的任何问题并且您执行上述所有操作,我建议您查看 yourProject.vcxproj 文件并检查它是否包含您的 MyClass.cpp 和源文件
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="myClass.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
</ItemGroup>
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
而不是作为
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h" />
<ClInclude Include="myClass.cpp" />
</ItemGroup>
SynthProject.vcxproj
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="myClass.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="myClass.cpp">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
我已经设法手动执行此操作,但如果您没有或不使用 git,建议您卸载文件并将其重新添加到项目中。
评论
void myFunc() { /* do stuff */ }
void A::myFunc() { /* do stuff */ }
void myFunc() {};