加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 07:32:09 所属栏目:百科 来源:网络整理
导读:这是.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 getTresho
这是.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文件.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读