Export QObject based class from DLL
- 
If you want to export a C++ class from a DLL (Windows), you need to declare it with proper __declspec(dllexport) (if building the DLL) or __declspec(dllimport) (when using the DLL). That's just what Windows wants you to do, and it is normally done with properly defined preprocessor macros, like class MYDLL_EXPORT myClass { ... }But if now this class happens to be derived from QObject, this is not working any more - and I have not found a solution yet: class MYDLL_EXPORT myClass: public QObject { Q_OBJECT ... }The point is that this header will have to be MOC'ed, and this tool will generate some code that is not allowed together with __declspec(dllimport) and the compiler gives an error message like this: moc_myClass.cpp(89): error C2491: 'atgCategoriesManager::staticMetaObject': definition of dllimport static data member not allowedand that's it! Now the point is that I used Google and found MANY mentions of this problem, but bad enough: not one single solution! So my question still remains: What can I do so solve that problem? The point is simply: the Q_OBJECT macro generates code that is not acceptable for the MSVC compiler if you do not only export it from a dll, but also want to import it - which is finally the purpose of any DLL! It really starts to drive me a little crazy: Maybe I should totally redesign my software and make sure that QObject derived classes are never exported from DLLs!?? 
- 
Conclusion: problem solved - thanks to the hint of VRonin! An additional hint I found somewhere else for CMake users. There you can do it as follows: In the configuration file you need this: INCLUDE(GenerateExportHeader) SET(MOC_SOURCES) QT5_WRAP_CPP( MOC_SOURCES myDllClass.h ) ADD_LIBRARY(MyDll SHARED myDllClass.h myDllClass.cpp ${MOC_SOURCES} ) GENERATE_EXPORT_HEADER(MyDll)Then in the header file you need: #include <mydll_export.h> class MYDLL_EXPORT atgCategoriesManager: public QObject { Q_OBJECT ...This seems to be the most elegant way if you are working with CMake: the GENERATE_EXPORT_HEADER macro will generate that mydll_export.h file that keeps all that Microsoftish blah-blah, so your real code stays nice, clean and readable. 
- 
Hi, Did you follow Qt's documentation about creating shared libraries ? There should be no problem for QObject based classes. 
- 
Only way I can think of is through exported C functions which are wrapped around the object calls. This not a elegant but it works. 
- 
If you want to export a C++ class from a DLL (Windows), you need to declare it with proper __declspec(dllexport) (if building the DLL) or __declspec(dllimport) (when using the DLL). That's just what Windows wants you to do, and it is normally done with properly defined preprocessor macros, like class MYDLL_EXPORT myClass { ... }But if now this class happens to be derived from QObject, this is not working any more - and I have not found a solution yet: class MYDLL_EXPORT myClass: public QObject { Q_OBJECT ... }The point is that this header will have to be MOC'ed, and this tool will generate some code that is not allowed together with __declspec(dllimport) and the compiler gives an error message like this: moc_myClass.cpp(89): error C2491: 'atgCategoriesManager::staticMetaObject': definition of dllimport static data member not allowedand that's it! Now the point is that I used Google and found MANY mentions of this problem, but bad enough: not one single solution! So my question still remains: What can I do so solve that problem? The point is simply: the Q_OBJECT macro generates code that is not acceptable for the MSVC compiler if you do not only export it from a dll, but also want to import it - which is finally the purpose of any DLL! It really starts to drive me a little crazy: Maybe I should totally redesign my software and make sure that QObject derived classes are never exported from DLLs!?? @CoBo 
 the case you described definitely works as expected.
 How does yourMYDLL_EXPORTmacro look like? I guess you just forgot to define the macro which switched between import/export?
- 
Thanks for your quick replies! Actually I found and followed that link by SGaist for long - and it did not work for me if the class is derived from QObject. And answering to raven-worx: I am pretty sure that I did it all as advertised: In the cpp I have code like #define DEF_MYDLL #include <myDll.h>and in the header it looks like this: #ifdef DEF_MYDLL #define MYDLL_EXPORT Q_DECL_EXPORT #else #define MYDLL_EXPORT Q_DECL_IMPORT #endif class MYDLL_EXPORT myDllClass: public QObject { Q_OBJECT ...I am pretty sure that this is correct. Right at this moment I am busy implementing a solution that is similar to what dheerendra is proposing: I generate a "singleton" class in plain C++ in the way as described - with the macro Microsoft blablah. Which so far seems to work: it compiles, links - and I can pass a single "int" value from one DLL to another! Next step I will try to extend this as kind of a global "singleton class manager": In the main program I generate the different singleton classes and give the pointers to that "manager", and in other DLLs I retrieve the pointers from the manager and do whatever is required. And I guess that in this way I should also be able to handle classes/objects that are derived from QObject - because they will always only reside in the main program. PS: I have one guess why it might be possible that still both statements are true: "it works" and "it doesn't". I see that my own class is not only derived from QObject, but includes also a static function. It is not defined in the header, so I don't see why there SHOULD be trouble, but maybe the error message is actually wrong: it complains about the "staticMetaObject" (which is a MOC product), but maybe the real root cause is still the fact that there is a static function in the class!?? However, no time yet to check this option. 
- 
The export of QObjectworks, Qt uses it extensively internally. It also works with custom made libraries see this for an example.The problem you have is that DEF_MYDLLshould not go in the source or header files with#define DEF_MYDLLbut should be passed to the compiler preprocessors.- In qmake/Qt Creator you can change the .pro file by adding DEFINES += DEF_MYDLLand re-running qmake
- in CMake add DEF_MYDLLto the privatetarget_compile_definitions, for exampletarget_compile_definitions(myLibrary PRIVATE DEF_MYDLL)
- in Visual Studio right click on the project->properties->C/C++->Preprocessor->Preprocessor Definitions->Edit and append  DEF_MYDLLto the list (repeat the process for Debug, Release, 32 and 64bit versions using the comboboxes at the top)
 Now the point is that I used Google and found MANY mentions of this problem, but bad enough: not one single solution! If the above solves your problem could you post a link to this topic to the other forums you googled so the next time if someone googles he'll find the solution? 
- In qmake/Qt Creator you can change the .pro file by adding 
- 
The export of QObjectworks, Qt uses it extensively internally. It also works with custom made libraries see this for an example.The problem you have is that DEF_MYDLLshould not go in the source or header files with#define DEF_MYDLLbut should be passed to the compiler preprocessors.- In qmake/Qt Creator you can change the .pro file by adding DEFINES += DEF_MYDLLand re-running qmake
- in CMake add DEF_MYDLLto the privatetarget_compile_definitions, for exampletarget_compile_definitions(myLibrary PRIVATE DEF_MYDLL)
- in Visual Studio right click on the project->properties->C/C++->Preprocessor->Preprocessor Definitions->Edit and append  DEF_MYDLLto the list (repeat the process for Debug, Release, 32 and 64bit versions using the comboboxes at the top)
 Now the point is that I used Google and found MANY mentions of this problem, but bad enough: not one single solution! If the above solves your problem could you post a link to this topic to the other forums you googled so the next time if someone googles he'll find the solution? @VRonin Wow, that sounds really promising - and I have not seen it mentioned otherwise! Also not tried at this moment, but somehow makes sense. Although I must say that some of the readings were talking about adding the defines to the qmake configuration, but since I am working with CMake (+QtCreator) this did not look adequate for me. But since you seem to really understand that issue I have one additional understanding question: If I add the definition to the configuration (be it qmake, cmake or vs) I basically add it either to that specific C++ implementation file (like I do it with the #define...), or I add it to all files - which then "kills" the effect because it will be defined wherever the header is included - no? What I guess is that "somehow" it has to be made sure that it is also defined in some MOC generated files - and that your method SOMEHOW does this trick!? Ah, ok: if I do target_compile_definitions(myLibrary PRIVATE DEF_MYDLL) I actually add it to whatever is compiled into that library - and that indeed includes also the "MOC products"... Right!? Regarding your last remark I am not sure I will be able to really do it - because after seeing these instructions with the macros so many times - without your important hint! - I did not really keep these links any more... 
- In qmake/Qt Creator you can change the .pro file by adding 
- 
@VRonin Wow, that sounds really promising - and I have not seen it mentioned otherwise! Also not tried at this moment, but somehow makes sense. Although I must say that some of the readings were talking about adding the defines to the qmake configuration, but since I am working with CMake (+QtCreator) this did not look adequate for me. But since you seem to really understand that issue I have one additional understanding question: If I add the definition to the configuration (be it qmake, cmake or vs) I basically add it either to that specific C++ implementation file (like I do it with the #define...), or I add it to all files - which then "kills" the effect because it will be defined wherever the header is included - no? What I guess is that "somehow" it has to be made sure that it is also defined in some MOC generated files - and that your method SOMEHOW does this trick!? Ah, ok: if I do target_compile_definitions(myLibrary PRIVATE DEF_MYDLL) I actually add it to whatever is compiled into that library - and that indeed includes also the "MOC products"... Right!? Regarding your last remark I am not sure I will be able to really do it - because after seeing these instructions with the macros so many times - without your important hint! - I did not really keep these links any more... @CoBo said in Export QObject based class from DLL: Ah, ok: if I do target_compile_definitions(myLibrary PRIVATE DEF_MYDLL) I actually add it to whatever is compiled into that library - and that indeed includes also the "MOC products" Correct. That's basically equivalent to add #define DEF_MYDLLat the top of every header and source file for that target
- 
Conclusion: problem solved - thanks to the hint of VRonin! An additional hint I found somewhere else for CMake users. There you can do it as follows: In the configuration file you need this: INCLUDE(GenerateExportHeader) SET(MOC_SOURCES) QT5_WRAP_CPP( MOC_SOURCES myDllClass.h ) ADD_LIBRARY(MyDll SHARED myDllClass.h myDllClass.cpp ${MOC_SOURCES} ) GENERATE_EXPORT_HEADER(MyDll)Then in the header file you need: #include <mydll_export.h> class MYDLL_EXPORT atgCategoriesManager: public QObject { Q_OBJECT ...This seems to be the most elegant way if you are working with CMake: the GENERATE_EXPORT_HEADER macro will generate that mydll_export.h file that keeps all that Microsoftish blah-blah, so your real code stays nice, clean and readable. 
