Solved 'Undefined interface' when I put interface implamentation in another dll
-
Hello everyone!
I am new in qt. I have a problem in VS2015 and my Qt version is 5.8.0.Our project is an Image viewer, so we need some extensibility for different views, datas or filters(process the images). We design all of them from one abstract class 'ModelItem'.
First, I declare an interface in one project called ivQtCore. It will be generated in ivQtCore.dll. Here the header code is:#ifndef ModelItemInterface_h #define ModelItemInterface_h #include <QtPlugin> #include "ivQtCoreModule.h"// for export #define ModelItem_IID "com.kmust-bme/imageview/modelItem" //the IID class ModelItem;// an abstract class which has some subclasses for views,fitlers or something class IVQTCORE_EXPORT ModelItemInterface { public: ModelItemInterface(); virtual ~ModelItemInterface(); // a method to create subclass object by type and name virtual ModelItem* createItem (const QString& type, const QString& name) const = 0; }; Q_DECLARE_INTERFACE (ModelItemInterface, ModelItem_IID ) #endif
Second, I try to write an implementation class 'StandardImplModelItemInterface' in ivQtCore and it works well!!!
Third, the VS have a solution with many projects. So I try to move the implementation into another project(another dll), because ivQtCore should only control the core logic, which only has some abstract or singleton classes. I call the new project ivQtStandardImpl and move the subclasses of ModelItem and StandardImplModelItemInterface in there while we got an error:
error Undefined interface ivQtStandardImpl *****\StandardImpl\StandardImplModelItemInterface.h 15
VS tell me that ' Q_INTERFACES(ModelItemInterface)' is undefined. The implementation header code is :
#ifndef StandardImplModelItemInterface_h #define StandardImplModelItemInterface_h #include "ivQtStandardImplModule.h"// for export #include <ModelItemInterface.h> #include <QObject> class IVQTSTANDARDIMPL_EXPORT StandardImplModelItemInterface: public QObject, public ModelItemInterface { Q_OBJECT Q_INTERFACES(ModelItemInterface) public: StandardImplModelItemInterface(QObject* parent); ~StandardImplModelItemInterface(); ModelItem* createItem (const QString& type, const QString& name) const ; QList<QMap<QString, QString> > getItemTypes (const QString& group); }; #endif
One thing confused me that it works well when I put the declare and implementation in one project(dll).
At the start, I think it's an include error. But I checked the 'addtional include directory' of ivQtStandardImpl where has already had the path to 'ModelItemInterface.h'.And, we use the CMake to manage the solution. Does it have any potential impact?
Wait for your answer,
HYS -
Finally, I solved it. The MOC process is happend before compliing.
The Q_INTERFACES is a kind of MOC. In Cmake, Qt should use QT5_WRAP_CPP to generate moc files.So it needs the right include path before MOC process, which means that I need set INCLUDE_DIRECTORIES (in CMakeList file) first, and then use Qt Macro QT5_WRAP_CPP.
I make a test. One project is echowindow and another is echoplugin. echoplugin's CMakeLists.txt is like this:PROJECT(echoplugin) # set the right include path first! INCLUDE_DIRECTORIES( D:/WS_VS/TestQtPlugin/TestQtPlugin/echowindow-----where the interface declare is ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) # then use the moc macro QT5_WRAP_CPP(MOC_BUILT_SOURCES echoplugin.h) set(echoplugin_SOURCE_FILES echoplugin.cpp echoplugin.h ${MOC_BUILT_SOURCES}) ADD_LIBRARY(echoplugin ${echoplugin_SOURCE_FILES}) TARGET_LINK_LIBRARIES(echoplugin LINK_PUBLIC ${Qt5_LIBRARIES} )
It solved!~~~~