0

This forum contains many examples of such situation, but in my case static variables are defined correctly, however I still get that error. So this issue is not duplicate of previous and above link does not answer the question. Suggested 21 answers post does not have solution Simon gave me here, please unmark this as "duplicate".

Seems I've declared all correctly, check this:

.h file:

class ValueSetsModelsContainer : public QObject
{
  Q_OBJECT

public:
  static void DLLEXPORT loadAllergiesValueSets(MPTDatabase *db);
  static void DLLEXPORT loadProceduresValueSets(MPTDatabase *db);

  // Models access functions
  static QStandardItemModel *drugsModel();
  static QStandardItemModel *substanceModel();
  static QStandardItemModel *reactionsModel();

private:
  static QStandardItemModel *myDrugsModel, *mySubstanceModel, *myReactionsModel;
};

.cpp:

QStandardItemModel *ValueSetsModelsContainer::myDrugsModel = 0;
QStandardItemModel *ValueSetsModelsContainer::mySubstanceModel = 0;
QStandardItemModel *ValueSetsModelsContainer::myReactionsModel = 0;

QStandardItemModel *ValueSetsModelsContainer::drugsModel()
{
  return ValueSetsModelsContainer::myDrugsModel;
}

QStandardItemModel *ValueSetsModelsContainer::substanceModel()
{
  return ValueSetsModelsContainer::mySubstanceModel;
}

QStandardItemModel *ValueSetsModelsContainer::reactionsModel()
{
  return ValueSetsModelsContainer::myReactionsModel;
}

So static variables are defined in cpp, however I still get linking error in another module which calls ValueSetsModelsContainer methods:

  • allergiesdialog.obj:-1: error: LNK2001: unresolved external symbol "private: static class QStandardItemModel * ValueSetsModelsContainer::myDrugsModel" (?myDrugsModel@ValueSetsModelsContainer@@0PAVQStandardItemModel@@A)
  • allergiesdialog.obj:-1: error: LNK2001: unresolved external symbol "private: static class QStandardItemModel *
    ValueSetsModelsContainer::mySubstanceModel"
    (?mySubstanceModel@ValueSetsModelsContainer@@0PAVQStandardItemModel@@A)
  • allergiesdialog.obj:-1: error: LNK2001: unresolved external symbol "private: static class QStandardItemModel *
    ValueSetsModelsContainer::myReactionsModel"
    (?myReactionsModel@ValueSetsModelsContainer@@0PAVQStandardItemModel@@A)

Where the problem could be?

Community
  • 1
  • 1
Aleksey Kontsevich
  • 4,671
  • 4
  • 46
  • 101
  • It is not a duplicate, above link does not answer my question. – Aleksey Kontsevich Oct 02 '15 at 20:58
  • Do you link all your objects (compiled cpp files) directly into your final binary? Or do you have some library involved? Could you add your .pro file to make the project structure clear? – Simon Warta Oct 02 '15 at 21:09
  • Seems yes - directly. PRO and included PRIs are very big - many cpp and h files to include here. – Aleksey Kontsevich Oct 02 '15 at 21:15
  • Could you add the link command that is executed before the error appears? – Simon Warta Oct 02 '15 at 21:33
  • link /LIBPATH:"c:\Qt\4.8.7\lib" /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /MANIFEST /MANIFESTFILE:"./debug\PAR3.intermediate.manifest" /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /OUT:..\dbgbin\PAR3.exe @C:\Users\ALEKSE~1.ALE\AppData\Local\Temp\nm6246.tmp Creating library ..\dbgbin\PAR3.lib and object ..\dbgbin\PAR3.exp allergiesdialog.obj : error LNK2019: unresolved external symbol "public: static class QStandardItemModel * __cdecl ValueSetsModelsContainer – Aleksey Kontsevich Oct 02 '15 at 21:45
  • I don't think it makes sense that the linker creates a .lib file (PAR3.lib) when the link target is an executable file (PAR3.exe). What is the purpose of the `DLLEXPORT` constant when you are not planning to create a DLL? – Simon Warta Oct 02 '15 at 21:59
  • Cause without it I get another error: main.obj:-1: error: LNK2019: unresolved external symbol "public: static void __cdecl ValueSetsModelsContainer::loadProceduresValueSets(class MPTDatabase *)" (?loadProceduresValueSets@ValueSetsModelsContainer@@SAXPAVMPTDatabase@@@Z) referenced in function _main – Aleksey Kontsevich Oct 02 '15 at 22:13
  • If I put DLLEXPORT to class definition then another error: C:\MPT\trunk\EMRDatabase2\CodeSystemDB\valuesetsmodelscontainer.h:44: error: C2487: 'mySubstanceModel' : member of dll interface class may not be declared with dll interface – Aleksey Kontsevich Oct 02 '15 at 22:14
  • This is interesting: "main.obj:-1: error: LNK2019: unresolved external symbol "public: static void __cdecl ValueSetsModelsContainer::loadProceduresValueSets(class MPTDatabase *)" (?loadProceduresValueSets@ValueSetsModelsContainer@@SAXPAVMPTDatabase@@@Z) referenced in function _main". It says that your `loadProceduresValueSets()` is only available in the `main()` via a library (I guess a DLL). You really should check your project setup and post everything of interest from your .pro and pri files. – Simon Warta Oct 02 '15 at 22:19
  • Yes, preloading called in main(), result - models are used in dialogs - another objects. – Aleksey Kontsevich Oct 02 '15 at 22:22
  • 1
    Try this `static DLLEXPORT QStandardItemModel *drugsModel();` in your .h file – Simon Warta Oct 02 '15 at 22:27
  • Hmm... works, I'd tried that already with no luck :) Now, works, thanks! – Aleksey Kontsevich Oct 02 '15 at 22:38
  • Hey πάντα ῥεῖ, how to put above Simon's comment as an answer to the ticket? – Aleksey Kontsevich Oct 02 '15 at 22:42
  • 1
    Voting to re-open so comment can be converted to answer. This doesn't smell like a dupe to me. – Joshua Oct 02 '15 at 22:47
  • @Simon Warta, could You move Your comment to the answers please? Thanks! – Aleksey Kontsevich Oct 04 '15 at 12:35

1 Answers1

1

From your link commands it turned out that you are linking together objects into a DLL and then in a second step link the DLL with your final binary. This might be caused by a subdirs template in your project settings.

Whenever you want to have a method of a DLL available from outside, you need to make it available via __declspec( dllexport ). I guess this is done in your custom precompiler constant DLLEXPORT.

Now try this in your .h file:

static DLLEXPORT QStandardItemModel *drugsModel();
static DLLEXPORT QStandardItemModel *substanceModel();
static DLLEXPORT QStandardItemModel *reactionsModel();

to make those methods available from outside the DLL.


By the way: I don't think it makes sense here to have an intermediate dynamic library (DLL) if you are just linking stuff from your own project and don't need to make it available to someone else. Consider using a static library instead by setting TEMPLATE = lib and CONFIG += staticlib in the .pro file where ValueSetsModelsContainer is in. But this is another topic and another question.

Simon Warta
  • 10,850
  • 5
  • 40
  • 78