未解析的外部符号静态变量(由标头中定义的方法使用的变量) [英] Unresolved external symbol static variable (variable used by method defined in header)

查看:124
本文介绍了未解析的外部符号静态变量(由标头中定义的方法使用的变量)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是.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:无法解析的外部符号专用:静态int TransformationViewer_Utility_Logging :: Logger :: mTresholdSeverity"(?mTresholdSeverity @ Logger @ TransformationViewer_Utility_Logging @@ 0HA)...

I get this error:
error LNK2001: unresolved external symbol "private: static int TransformationViewer_Utility_Logging::Logger::mTresholdSeverity" (?mTresholdSeverity@Logger@TransformationViewer_Utility_Logging@@0HA) ...

显然,mTresholdSeverity已初始化.如果我将getTresholdSeverity()和setTresholdSeverity()注释掉,或者将它们的定义移到.cpp文件中,该错误将被消除.

Obviously, mTresholdSeverity is initialized. The error is removed if I comment out getTresholdSeverity() and setTresholdSeverity() or if I move their definition into .cpp file.

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

Why is there a link error when a static method defined in header file (getTresholdSeverity() or setTresholdSeverity()) uses a static variable (mTresholdSeverity)?

推荐答案

这是它的工作方式.

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

Every DLL (or EXE) or otherwise complete "fully-linked" binary, must have definitions of all referenced names, including static variables, including static data members in C++ classes.

它们将在应用程序中的DLL中分开.这意味着此变量值将有所不同,具体取决于您从哪个DLL中查找.将函数移到CPP文件将使它们做另一件事:它们现在将看到DLL的变量副本,而不是EXE的副本.

They will be separate across DLLs in the application. That means, this variable value will be different, depending on which DLL you look from. Moving the functions to CPP file will make them do a different thing: they will now see the DLL's copy of the variable and not the EXE's.

要使您编写的内容编译,必须在所有位置的所有用户二进制文件中都存在CPP的定义.这意味着,DLL和DLL的用户(EXE或DLL)必须具有一个具有此定义的CPP文件.

To make what you wrote compile, there has to be the definition from the CPP present in all user binaries at one place. That means, the DLL and the users of the DLL (EXEs or DLLs) must have one CPP file with this definition.

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

This is a very big hassle, because among other things it makes Singleton pattern impossible (having a shared data object for all users within the program) and each copy of a DLL must have its own static state. Such problem exists only on Windows, with DLLs which are dynamic *loaded * libraries. On UNIX systems, there is a different technology known as Shared Objects (SO). They support true dynamic linking, which means, running the linker to resolve external names at runtime.

这篇关于未解析的外部符号静态变量(由标头中定义的方法使用的变量)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆