C++ 从 DLL 导出全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3097548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:02:17  来源:igfitidea点击:

Exporting global variables from DLL

c++visual-studiodlldllimport

提问by Gili

I'm trying to export a global variable from a DLL.

我正在尝试从 DLL 导出全局变量。

Foo.h

foo.h

class Foo
{
public:
    Foo()
    {}
};

#ifdef PROJECT_EXPORTS
    #define API __declspec(dllexport)
#else
    #define API __declspec(dllimport)
#endif

API const Foo foo;

Foo.cpp

文件

#include "Foo.h"

const Foo foo;

When I compile the above code, Visual Studio complains:

当我编译上面的代码时,Visual Studio 抱怨:

foo.cpp(3) : error C2370: 'foo' : redefinition; different storage class 1> foo.h(14) : see declaration of 'foo'

foo.cpp(3):错误 C2370:'foo':重新定义;不同的存储类 1> foo.h(14) :参见“foo”的声明

If I use:

如果我使用:

external const Foo foo;

in Foo.h the compiler is happy but then the DLL does not export the symbol. I've managed to export functions with problems, but variables don't seem to work the same way... Any ideas?

在 Foo.h 中,编译器很高兴,但 DLL 不会导出符号。我设法导出有问题的函数,但变量的工作方式似乎不同......有什么想法吗?

回答by Commodore Jaeger

In your header:

在您的标题中:

API extern const Foo foo;

In your source file:

在您的源文件中:

API const Foo foo;

If you don't have the externkeyword, your C compiler assumes you mean to declare a local variable. (It doesn't care that you happened to have included the definition from a header file.) You also need to tell the compiler that you're planning on exporting the variable when you actually declare it in your source file.

如果您没有extern关键字,您的 C 编译器会假定您打算声明一个局部变量。(它并不关心您是否碰巧包含了头文件中的定义。)您还需要告诉编译器您计划在源文件中实际声明变量时导出它。

回答by zar

The class Foomost likely will have member functions in reality, calling those from another module would cause linker errors with the OP/accepted answer. The class must be defined as dll export/import as well in order to use the exported instance of it outside this module to eliminate the link errors.

该类Foo很可能在现实中具有成员函数,从另一个模块调用这些函数会导致链接器错误与 OP/接受的答案。该类也必须定义为 dll 导出/导入,以便在此模块之外使用它的导出实例来消除链接错误。

class API Foo
{
public:
    Foo()
    {}
    void DoSomeWork(); // calling this would cause link error if Foo is not defined as import/export class
};

With that said, it might be better to rename #defineAPI with something like DLLEXPORT so it makes sense for both APIs and export class.

#define话虽如此,最好将API重命名为 DLLEXPORT 之类的东西,这样对 API 和导出类都有意义。