C++ 未解决的外部符号问题

C++ 未解决的外部符号问题,c++,visual-studio-2010,visual-c++,C++,Visual Studio 2010,Visual C++,我有个问题。我有一个错误,我不知道为什么会发生 2>Home.obj : error LNK2019: unresolved external symbol "**void __cdecl LogAString(char *,...)**" (?LogAString@@YAXPADZZ) referenced in function "**public: static void __cdecl X::Home::HomeStart(void)**" (?HomeStart@Home@X@@

我有个问题。我有一个错误,我不知道为什么会发生

2>Home.obj : error LNK2019: unresolved external symbol "**void __cdecl LogAString(char *,...)**" (?LogAString@@YAXPADZZ) referenced in function "**public: static void __cdecl X::Home::HomeStart(void)**" (?HomeStart@Home@X@@SAXXZ)
2>Widget.obj : error LNK2001: unresolved external symbol "void __cdecl LogAString(char *,...)" (?LogAString@@YAXPADZZ)
2>J:\src\out.dll : fatal error LNK1120: 1 unresolved externals
这是我的密码:

Log.h

我想我已经分别在头文件和cpp文件中声明和定义了函数。为什么我会犯这些错误?我已经做了几个小时了,但仍然不知道为什么会发生这种情况。在VS2010上使用VC++


目前我没有使用任何其他外部库。编译目标是一个DLL,“out.DLL”。

可能名称空间与之有关,它在没有名称空间X的情况下工作吗?

这是链接器错误,而不是编译器错误。这意味着您正确地引用了代码中的头文件。事实上,您的代码编译成功

但是,然后链接器出去寻找它所指向的库中的引用函数,然后空手而归。库引用在VC++项目的属性表中定义。您的项目是否正在输出Out.dll?看起来链接器需要一个。我将调查链接器部分以及编译生成的文件


发布更多关于您的构建和解决方案/项目配置的信息,或者更好的是,如果您的属性表中没有足够的信息,那么可以发布更多的信息

您是否记得将
Log.cpp
添加到您的项目中


如果是,则在十六进制编辑器中打开文件
log.obj
。搜索字符串
LogAnError
。这将是一个更大的装饰字符串的一部分。将其与链接器无法解析的内容进行比较。识别差异并修复您的
LogAnError
函数,以便它们再次匹配。

好,根据您的评论:

编译目标是一个DLL,“out.DLL”

我假设您正在其他项目中使用此out.dll。当您尝试这样做时,会出现上述链接器错误。如果是这种情况,这是因为您没有导出函数。此外,拥有这样的全局函数是一种糟糕的做法。您至少应该将它们包装在一些类中,例如Utils或somethng,并将它们声明为静态:

示例Log.h:

#pragma once

#include <iostream>
#include <cstdarg>

class __declspec (dllexport) Utils
{
    public:
          static void LogAString(char* fmt, ...);
          static void LogAnError(char* fmt, ...);
};
#pragma一次
#包括
#包括
类declspec(dllexport)Utils
{
公众:
静态空隙对数(char*fmt,…);
静态无效日志错误(字符*fmt,…);
};
Log.cpp应该保持几乎相同

#include "Log.h"

#include <Util/String/String Formatting.h> // defines format(). Does not have any errors or issues.

void Utils::LogAString(char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
};

void Utils::LogAnError(char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    auto formatted_string = format("ERROR: %s", fmt).c_str();
    LogAString(const_cast<char*>(formatted_string), ap);

    va_end(ap);
};
#包括“Log.h”
#include//defines format()。没有任何错误或问题。
void Utils::LogAString(char*fmt,…)
{
va_列表ap;
va_启动(ap、fmt);
vprintf(fmt,ap);
va_端(ap);
};
void Utils::LogAnError(char*fmt,…)
{
va_列表ap;
va_启动(ap、fmt);
自动格式化的字符串=格式(“错误:%s”,fmt).c_str();
LogAString(const_cast(格式化字符串),ap);
va_端(ap);
};
现在,当您使用.dll时,您的函数将被导出并可用于其他项目。您还应该在include目录中包含Log.h文件,并确保“out.dll”位于主项目的同一输出文件夹中。此外,还应将out.lib添加到其他库中


希望这是你的问题。下次提供更多详细信息。

这些日志是在一个单独的项目中吗?@FaileDev,它在同一个项目中。事实上,我确实编译了您的代码并执行了它,它运行得很好。所以你要么有两个项目,要么发生了一些神奇的事情……我想可能是VisualStudioMagic。我以前也遇到过类似的问题,这些问题都是通过创建一个相同的项目并进行编译来解决的。我回家后会试试。如果你只是猜测,那么你应该发表评论,而不是回答。好的,谢谢你的提醒。我会记住的。我相对来说是新手,所以我仍然在摸索最好的做事方式。我应该添加什么样的信息?我还想补充一点,目前我没有使用任何其他外部库。编译目标是一个DLL“out.DLL”。我现在没有启动我的windows机器,但我认为我的VC++项目实际上引用了它们自己的输出DLL。如果这是正确的,那么我将对照输出部分中的路径检查链接器部分中的路径。看起来路径中应该有一个构建配置标志。也就是说,当您在调试中构建时,DLL的输出将是/Debug/Out.DLL。不过,我认为默认设置是正确的。这让我怀疑FailedDev是否正确,事实上,您正在尝试将第二个库链接到包含LogaString的库。哦,我不知道它引用了自己。我不想链接第二个库。所有内容都是自包含的,我在编译此库时遇到了错误。我刚刚启动了Windows环境以确认这一点。在我的一个DLL的属性表下(查看原始XML,而不必浏览GUI),我有一个VCLinkerTool部分,其中包含一个AdditionalDependencies节点,该节点包含mylibrary.lib和一个AdditionalLibraryDirectory节点,该节点设置为&(SolutionDir)\x64\$(ConfigurationName)。也许编译静态库和动态库是不同的,但值得一试。我认为这两个属性都在链接器部分下面。显然,路径中间的X64目录是特定于平台的。我相信有可能你有一个完全不同的输出路径,它不依赖于这些变量。我认为重要的是确保Out.dll的路径是正确的;我在编译库本身时遇到了错误。@alan那么你没有向我们展示你应该展示的东西。你的代码是编译的,这就是我所有的代码。我将在具有相同设置的新项目中重试。Perhaa Visual Studio再次扮演我,就像以前一样。(两个完全相同的项目。一个编译,另一个不编译)谢谢!出于某种奇怪的原因,VisualStudio的
#include "Home.h"
#include "Log.h"

namespace X {

void Home::HomeStart()
{
    while (true)
    {
        auto number_of_widgets = Widgets::Count();
        LogAString("Loading with %d widgets", number_of_widgets);
    }
}

} // namespace X
#pragma once

#include <iostream>
#include <cstdarg>

class __declspec (dllexport) Utils
{
    public:
          static void LogAString(char* fmt, ...);
          static void LogAnError(char* fmt, ...);
};
#include "Log.h"

#include <Util/String/String Formatting.h> // defines format(). Does not have any errors or issues.

void Utils::LogAString(char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vprintf(fmt, ap);
    va_end(ap);
};

void Utils::LogAnError(char* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    auto formatted_string = format("ERROR: %s", fmt).c_str();
    LogAString(const_cast<char*>(formatted_string), ap);

    va_end(ap);
};