Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exporting global variables from DLL

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

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:

foo.cpp(3) : error C2370: 'foo' : redefinition; different storage class 1> foo.h(14) : see declaration of '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?

like image 649
Gili Avatar asked Jun 22 '10 22:06

Gili


People also ask

Can DLL export classes?

You can declare C++ classes with the dllimport or dllexport attribute. These forms imply that the entire class is imported or exported. Classes exported this way are called exportable classes.

What is DLL export C++?

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages. You can use them to export and import functions, data, and objects to or from a DLL.

What is DLL export and import?

Dllexport is used to mark a function as exported. You implement the function in your DLL and export it so it becomes available to anyone using your DLL. Dllimport is the opposite: it marks a function as being imported from a DLL.


2 Answers

In your header:

API extern const Foo foo; 

In your source file:

API const Foo foo; 

If you don't have the extern keyword, 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.

like image 112
Commodore Jaeger Avatar answered Sep 19 '22 18:09

Commodore Jaeger


The class Foo most 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.

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 #define API with something like DLLEXPORT so it makes sense for both APIs and export class.

like image 35
zar Avatar answered Sep 19 '22 18:09

zar