gpt4 book ai didi

c++ - 未解析的外部符号静态变量(标题中定义的方法使用的变量)

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:12:03 25 4
gpt4 key购买 nike

这是.h:

class Logger
{
private:
static int mTresholdSeverity;

public:
static __declspec(dllexport) void log(const char* message);
static __declspec(dllexport) void logFormat(const char* format, ...);

static __declspec(dllexport) int getTresholdSeverity() { return mTresholdSeverity; }
static __declspec(dllexport) void setTresholdSeverity(int tresholdSeverity) { mTresholdSeverity = tresholdSeverity; }
};

和.cpp:

#include "Logger.h"
#include <cstdarg>

int Logger::mTresholdSeverity = 200;

void Logger::log(const char* message)
{
//...
}

void Logger::logFormat(const char* format, ...)
{
//...
}

我得到这个错误:
错误 LNK2001:未解析的外部符号“private: static int TransformationViewer_Utility_Logging::Logger::mTresholdSeverity” (?mTresholdSeverity@Logger@TransformationViewer_Utility_Logging@@0HA) ...

很明显,mTresholdSeverity被初始化了。如果我注释掉 getTresholdSeverity() 和 setTresholdSeverity() 或者如果我将它们的定义移动到 .cpp 文件中,错误就会被删除。

为什么头文件中定义的静态方法(getTresholdSeverity()或setTresholdSeverity())使用静态变量(mTresholdSeverity)会出现链接错误?

最佳答案

这是它的工作原理。

每个 DLL(或 EXE)或其他完整的“完全链接”二进制文件,都必须定义所有引用的名称,包括静态变量,包括 C++ 类中的静态数据成员。

它们将在应用程序中跨 DLL 分开。这意味着,这个变量值会有所不同,具体取决于您查看的是哪个 DLL。将函数移动到 CPP 文件将使它们做不同的事情:它们现在将看到变量的 DLL 拷贝而不是 EXE 的拷贝。

为了使您编写的内容能够编译,所有用户二进制文件中必须存在来自 CPP 的定义。这意味着,DLL 和 DLL 的用户(EXE 或 DLL)必须有一个包含此定义的 CPP 文件。

这是一个非常大的麻烦,因为除其他外,它使单例模式变得不可能(在程序中为所有用户提供共享数据对象)并且 DLL 的每个拷贝都必须有自己的静态状态。这种问题只存在于 Windows 上,DLL 是动态 *加载 * 库。在 UNIX 系统上,有一种称为共享对象 (SO) 的不同技术。它们支持真正的动态链接,这意味着运行链接器以在运行时解析外部名称。

关于c++ - 未解析的外部符号静态变量(标题中定义的方法使用的变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12229396/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com