PDA

View Full Version : CMake3.6 / VS2015 / Qt5.7 - lost in function-pointer based signals/slots across DLLs



NameRakes
6th January 2017, 22:21
Some details on my configuration + the problem:
I use the CMake Windows_Export_All_Symbols feature as explained here (https://blog.kitware.com/create-dlls-on-windows-without-declspec-using-new-cmake-export-all-feature/), and I don't worry about declspecs (dllimport/dllexport) any more.
As the title says, I use the new function-pointer approach for signals/slosts, to ensure type-safety at compile time.
When the signals/slots are in the same DLL, things are fine. Otherwise I get
unresolved external symbol "public: static struct QMetaObject const top::level1::mtree::MyWidget::staticMetaObject" - I don't believe namespace is a problem.
.

What have I researched, discovered and tried so far?
As stated in the CMake blog (https://blog.kitware.com/create-dlls-on-windows-without-declspec-using-new-cmake-export-all-feature/), the dll export feature of CMake doesn't work for static const members. They recommend "dllimport/dllexport" on those variables.
So I tried the solution from Qt (http://doc.qt.io/qt-5/sharedlibrary.html) (also mentioned in other blogs including this forum), like so:



#ifdef myWidget_DLL
#define myWidget_DLL_EXPORT Q_DECL_EXPORT
#else
#define myWidget_DLL_IMPORT Q_DECL_IMPORT
#endif

class myWidget_DLL_EXPORT MyWidget : public QDockWidget { ... };

# CMakeLists.txt entry to activate my macros
add_definitions (-DmyWidget_DLL)

But this doesn't work because CMake already does something like this, and myWidget_DLL_EXPORT in the class declaration is treated like a class/type, and not a macro.

So, how do I selectively export / import
QMetaObject const top::level1::mtree::MyWidget::staticMetaObject the variable found in moc_MyWidget.cpp. I tried exporting it from the moc_ file itself as a prototype, but it doesn't work - the compiler thinks I am trying to redefine the static meta object. What am I doing wrong? How do I resolve this. The constraint is that I don't want to close the CMake dll export feature, unless that is my last resort. Any pointers or suggestions is greatly appreciated.

d_stranz
6th January 2017, 23:27
I'm not so sure your class declaration is correct - you add the myWidget_DLL_EXPORT macro, but that will only be defined when you are building the DLL (i.e. myWidget_DLL defined). At import time, this macro is undefined and should lead to a compile error. I don't see any place where you use myWidget_DLL_IMPORT.

And you have remembered to add the Q_OBJECT macro to your class definition, right?

NameRakes
7th January 2017, 01:19
There is always the silly typo (which the developer alone doesn't see) is there to humble you. I had unintentionally defined a new macro (what else by cut'n'paste of that single line and blind replacement of EXPORT with IMPORT) for the clients. After you pointed out, changing the typo as follows fixes it:

// change the following
#define myWidget_DLL_IMPORT Q_DECL_IMPORT
// to redefining the "real" export macro as
#define myWidget_DLL_EXPORT Q_DECL_IMPORT
Thanks for your help!

I guess all the clean pure C++ code that I gained by using CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS variable is gone now. At least for the DLLs that emit signals ...