5

My problem is remarkably similar to this one: A class in a DLL has a static member. In this case, the static member is of Type QString (a QT type) and provides a name for the class. I provide the normal export on class level: __declspec(dllexport).

When I link the DLL with my class to another project and try to compile it, I get an "unresolved external symbol" error for the static data. I verified two things:

  1. Dumpbin definitely reports the static data member to be exported by compiled DLL.
  2. Actually, the static data member seems not to be used in the application which reports the error.

HEADER file (.h) in DLL is:

class __declspec(dllexport) MyClass {
public: 
   virtual ~MyClass();
   static const QString JUST_A_NAME;    
};

IMPLEMENTATION file (.cpp) in DLL is:

#include "MyClass.h"

MyClass::~MyClass() { }
const QString MyClass::JUST_A_NAME("call_me_al");

In contrast to already mentioned post, I avoided methods to be inline, e.g. implementation is obviously not in the header. The type, QString (see line 83 ff.), contains several inlines itself. May that cause the error?

EDIT: I added an import statement in the header of my application. It is located before any includes. HEADER file (.h) in APPLICATION is:

class __declspec(dllimport) MyClass {
public: 
   virtual ~MyClass();
   static const QString JUST_A_NAME;    
};

The error remains the same:

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>
Community
  • 1
  • 1
Finnfalter
  • 732
  • 2
  • 7
  • 22
  • 3
    I'd expect that your unresolved symbol is `MyClass::JUST_A_NAME` as the member is not present in the application. But that's not the root of the problem! You need to `__declspec(dllimport)` in the using application! I think that's enough to let the compiler figure out that you want to use the exported member from the DLL. – MFH Jan 31 '13 at 15:03
  • First thing I would check is "depends" (www.dependencywalker.com), whether the symbol is actually in the DLL. Then, as MFH correctly noted, you have to switch between import and export, which is explained in the link you provided yourself. Then, but that's just vague memory, I seem to remember that even if a class is generally exported, its static parts are not, so you have to explicitly add the import/export to its declaration. – Ulrich Eckhardt Jan 31 '13 at 20:24
  • Yes, MFH, Your guess about the unresolved error is right (see _EDIT_). On Your proposal, I added a `__declspec(dllimport)`, so far without success. doomster, as mentioned in the question, I had verified with _dumpbin_ that missing symbol is definitely exported in DLL. [Microsoft](http://msdn.microsoft.com/en-us/library/81h27t8c.aspx) says that _"[Doing] a class dllexport, all its member functions and static data members are exported."_ – Finnfalter Feb 01 '13 at 07:46

1 Answers1

11

In your application header file you need to do two things.

  1. When exporting, declare the definition __declspec(dllexport)
  2. When importing, declare the definition __declspec(dllimport)

You obviously cannot do them both at the same time.

What you have to do is define a macro like this:

#ifdef __COMPILING_MYLIB
#define MYLIBAPI __declspec(dllimport)
#else
#define MYLIBAPI __declspec(dllexport)
#endif

Then declare your exports like this:

// mylib.h
class MYLIBAPI MyClass {
public: 
   virtual ~MyClass();
   static const QString JUST_A_NAME;    
};

Then, when compiling MYLIB, you pass -D__COMPLING_MYLIB to the compiler, which triggers the #if above.

That way, when compiling the library itself, the header file declares things as exports, but when compiling things which will use the library, they are declared as imports.

Ben
  • 34,935
  • 6
  • 74
  • 113