代码之家  ›  专栏  ›  技术社区  ›  Gayan

在DLL中导出静态数据

  •  29
  • Gayan  · 技术社区  · 14 年前

    我有一个DLL,其中包含一个静态 成员 __declspec(dllexport) 为了利用这个班级的 . 但是,当我将它链接到另一个项目并尝试编译它时,静态数据会出现“未解析的外部符号”错误。

    例如 在DLL中,Test.h

    class __declspec(dllexport) Test{
    protected:
        static int d;
    public:
        static void m(){int x = a;}
    }
    

    在DLL中,Test.cpp

    #include "Test.h"
    
    int Test::d;
    

    在使用Test的应用程序中,我调用m()。

    如果我使用dumpbin检查DLL(the.lib),我可以看到符号已经被导出。

    1>Main.obj : error LNK2001: unresolved external symbol "protected: static int CalcEngine::i_MatrixRow" (?i_MatrixRow@CalcEngine@@1HA)
    

    但是.lib的dumpbin包含:

    Version      : 0
      Machine      : 14C (x86)
      TimeDateStamp: 4BA3611A Fri Mar 19 17:03:46 2010
      SizeOfData   : 0000002C
      DLL name     : CalcEngine.dll
      Symbol name  : ?i_MatrixRow@CalcEngine@@1HA (protected: static int CalcEngine::i_MatrixRow)
      Type         : data
      Name type    : name
      Hint         : 31
      Name         : ?i_MatrixRow@CalcEngine@@1HA
    

    我想不出怎么解决这个问题。我做错什么了?我怎样才能克服这些错误呢?

    另外,该代码最初是为Linux开发的,.so/二进制组合可以毫无问题地工作

    EDIT:在给定的情况下,静态变量不是由应用程序直接引用的,但是方法是内联的,因为它在头中。我能够通过将方法移动到.cpp文件来解决链接错误。

    3 回复  |  直到 14 年前
        1
  •  19
  •   Community Nick Dandoulakis    4 年前

    this

    静态成员不能由调用应用程序中的代码直接访问,只能通过dll中类的成员函数访问。但是有几个 访问静态成员的函数。这些函数将内联扩展到调用应用程序代码中,使调用应用程序直接访问静态成员。这将违反上面引用的发现,即静态变量是dll的本地变量,不能从调用应用程序引用。

        2
  •  15
  •   Ghislain Fourny    14 年前

    我猜使用DLL的类应该看到 德林波特 而不是 数据链路端口

    #ifdef EXPORTING
    #define DECLSPEC __declspec(dllexport)
    #else
    #define DECLSPEC __declspec(dllimport)
    #endif
    

    然后在类声明中使用它:

    class DECLSPEC Test{
    protected:
        static int d;
    public:
        static void m(){}
    }
    

    因此,在Test.cpp(或在DLL项目中有意义的任何地方)中,您可以指定要导出的内容,以便将其与一起导出 :

    #define EXPORTING
    #include "Test.h"
    
    int Test::d;
    

    德林波特 .

    有道理吗?

        3
  •  4
  •   Craig M. Brandenburg Martin    8 年前

    __declspec(dllexport) __declspec(dllimport) dllexport 应在编译DLL时使用, dllimport

    以下是visual studio示例:

    // The following ifdef block is the standard way of creating macros which make exporting 
    // from a DLL simpler. All files within this DLL are compiled with the DLL_EXPORTS
    // symbol defined on the command line. this symbol should not be defined on any project
    // that uses this DLL. This way any other project whose source files include this file see 
    // DLL_API functions as being imported from a DLL, whereas this DLL sees symbols
    // defined with this macro as being exported.
    #ifdef DLL_EXPORTS
    #define DLL_API __declspec(dllexport)
    #else
    #define DLL_API __declspec(dllimport)
    #endif
    
        4
  •  0
  •   Jack D Menendez    3 年前

    尽管有这样的摘要,但是可以从DLL导出静态数据。但是,Visual Studio DLL项目提供的标准宏出现了一个问题:

    #ifdef DLL_EXPORTS
    #define DLL_API __declspec(dllexport)
    #else
    #define DLL_API __declspec(dllimport)
    #endif
    

    如果有多个DLL将代码从一个DLL调用到另一个DLL,或者在EXE和DLL之间调用代码,则此宏将出现问题,因为每个头都将被导出。需要处理declspec的唯一宏。处理此问题的最安全方法如下:

    #ifdef MYPROJECT_DLL_EXPORTS
         #define MYPROJECT_API __declspec(dllexport)
    #else
         #define MYPROJECT_API __declspec(dllimport)
    #endif
    

    在标题代码中:

    struct/class MYPROJECT_API myclass {
       static int counter;
    };
    

    在.cpp文件中:

    int myclass::counter = 0;
    
        5
  •  -1
  •   Frank Liu    3 年前

    static inline std::string static_variable