Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ DLL中的静态数据_C++_Windows_Dll_Linker - Fatal编程技术网

C++ DLL中的静态数据

C++ DLL中的静态数据,c++,windows,dll,linker,C++,Windows,Dll,Linker,我的问题非常类似于:DLL中的类有一个静态成员。在本例中,静态成员的类型为(QT类型),并提供类的名称。我提供类级别的正常导出:\uu declspec(dllexport) 当我将带有类的DLL链接到另一个项目并尝试编译它时,静态数据会出现“未解析的外部符号”错误。我证实了两件事: Dumpbin明确报告要由编译的DLL导出的静态数据成员 实际上,在报告错误的应用程序中似乎没有使用静态数据成员 DLL中的头文件(.h)是: class __declspec(dllexport) MyClass

我的问题非常类似于:DLL中的类有一个静态成员。在本例中,静态成员的类型为(QT类型),并提供类的名称。我提供类级别的正常导出:
\uu declspec(dllexport)

当我将带有类的DLL链接到另一个项目并尝试编译它时,静态数据会出现“未解析的外部符号”错误。我证实了两件事:

  • Dumpbin明确报告要由编译的DLL导出的静态数据成员
  • 实际上,在报告错误的应用程序中似乎没有使用静态数据成员
  • DLL中的头文件(.h)是:

    class __declspec(dllexport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    #include "MyClass.h"
    
    MyClass::~MyClass() { }
    const QString MyClass::JUST_A_NAME("call_me_al");
    
    class __declspec(dllimport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    DLL中的实现文件(.cpp)是:

    class __declspec(dllexport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    #include "MyClass.h"
    
    MyClass::~MyClass() { }
    const QString MyClass::JUST_A_NAME("call_me_al");
    
    class __declspec(dllimport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    与post相比,我避免了内联方法,例如,实现显然不在标题中。类型(参见第83行及其后)本身包含多个内联线。这会导致错误吗

    编辑:我在应用程序的标题中添加了导入语句。它位于任何包含之前。 应用程序中的头文件(.h)是:

    class __declspec(dllexport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    #include "MyClass.h"
    
    MyClass::~MyClass() { }
    const QString MyClass::JUST_A_NAME("call_me_al");
    
    class __declspec(dllimport) MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    错误保持不变:

    error LNK2001: non resolved external symbol ""public: static class QString const MyClass::JUST_A_NAME" (?JUST_A_NAME@MyClass@@2VQString@@B)". <name of .obj file from application>
    
    错误LNK2001:未解析的外部符号“public:静态类QString const MyClass::JUST_A_NAME”(?JUST_A_NAME@MyClass@@2VQString@@B)”。
    
    在应用程序头文件中,您需要做两件事

  • 导出时,声明定义
    \uuuu declspec(dllexport)
  • 导入时,声明定义
    \uu declspec(dllimport)
  • 你显然不能同时做这两件事

    您需要做的是定义如下所示的宏:

    #ifdef __COMPILING_MYLIB
    #define MYLIBAPI __declspec(dllimport)
    #else
    #define MYLIBAPI __declspec(dllexport)
    #endif
    
    // mylib.h
    class MYLIBAPI MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    然后像这样声明您的导出:

    #ifdef __COMPILING_MYLIB
    #define MYLIBAPI __declspec(dllimport)
    #else
    #define MYLIBAPI __declspec(dllexport)
    #endif
    
    // mylib.h
    class MYLIBAPI MyClass {
    public: 
       virtual ~MyClass();
       static const QString JUST_A_NAME;    
    };
    
    然后,在编译MYLIB时,将
    -D_ucompling_MYLIB
    传递给编译器,这将触发上面的
    \if


    这样,在编译库本身时,头文件会将对象声明为导出,但在编译将使用库的对象时,它们会声明为导入。

    我希望未解析的符号是
    MyClass::JUST_A_NAME
    ,因为应用程序中不存在成员。但这不是问题的根源!您需要在使用应用程序中
    \u declspec(dllimport)
    !我认为这足以让编译器知道您想要使用DLL中导出的成员。我要检查的第一件事是“dependencywalker”(www.dependencywalker.com),即符号是否实际在DLL中。然后,正如MFH正确指出的,您必须在导入和导出之间切换,这在您自己提供的链接中进行了解释。然后,但那只是模糊的记忆,我似乎记得,即使一个类通常是导出的,它的静态部分也不是,所以你必须显式地将导入/导出添加到它的声明中。是的,MFH,你对未解决错误的猜测是对的(参见编辑)。根据你的建议,我添加了一个
    \uu declspec(dllimport)
    ,但迄今为止没有成功。正如问题中提到的,我已经用dumpbin验证了丢失的符号肯定是在DLL中导出的。表示“[执行]类dllexport时,将导出其所有成员函数和静态数据成员。”