未解决的外部符号问题

时间:2011-11-01 20:08:58

标签: 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@@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

#pragma once

#include <iostream>
#include <cstdarg>

void LogAString(char* fmt, ...);
void LogAnError(char* fmt, ...);

Log.cpp

#include "Log.h"

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

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

void 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);
};

Home.cpp(摘录)

#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

我以为我已经分别声明和定义了header和cpp文件中的函数。为什么我会收到这些错误?我已经在这里待了几个小时,但仍然不确定为什么会这样。在VS 2010上使用VC ++。

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

4 个答案:

答案 0 :(得分:3)

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

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

发布有关构建和解决方案/项目配置的更多信息,如果信息不足,甚至可以更好地确定属性表中的内容。

答案 1 :(得分:1)

您还记得在项目中添加Log.cpp吗?

如果是,则在十六进制编辑器中打开文件log.obj。搜索字符串LogAnError。它将是更大的装饰字符串的一部分。 Use the undname command to undecorate it。将其与链接器无法解析的内容进行比较。确定差异并修复LogAnError功能,使其再次匹配。

答案 2 :(得分:0)

也许命名空间与它有关,没有命名空间X吗?

答案 3 :(得分:0)

好的,基于你的评论:

  

编译目标是一个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, ...);
};

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);
};

现在,当您使用.dll时,您的功能将被导出并可供您的其他项目使用。您还应该在include目录中包含Log.h文件,并确保“out.dll”位于主项目的同一输出文件夹中。另外,您应该将out.lib添加到其他库中。

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

相关问题