2

I'm developping a c++/Qt program that will have several plugins. For each class I have to define a plugin-interface that looks like this:

//my class
class qwerty;

//my interface
class qwertyPlug : public QObject, myPlug { 
Q_OBJECT 
Q_INTERFACES(nPanPlug) 
Q_PLUGIN_METADATA(IID "org.myapp.plug") 
public: 
  qwertyPlug() {qRegisterMetaType<qwerty *>("qwerty""*");} 
  QByteArray name() {return "qwerty";} 
};

I created a macro (actually 2 since I'm not a c++ preprocessor guru):

#define MY_PLUGIN_BASE(__c_name,__appendix)                                 \
  class __c_name##__appendix : public QObject, myPlug {                     \
  Q_OBJECT                                                                  \
  Q_INTERFACES(nPanPlug)                                                    \
  Q_PLUGIN_METADATA(IID "org.myapp.plug")                                   \
  public:                                                                   \
      __c_name##__appendix() {qRegisterMetaType<__c_name *>(#__c_name"*");} \
      QByteArray name() {return #__c_name;}                                 \
  };

#define MY_PLUGIN(__c_name) MY_PLUGIN_BASE(__c_name,Plug)

so that In my code (where qwerty is defined) I just have to add:

MY_PLUGIN(qwerty)

which will expand (output of g++ -E):

class qwertyPlug : public QObject, myPlug { Q_OBJECT Q_INTERFACES(nPanPlug) Q_PLUGIN_METADATA(IID "org.myapp.plug") public: qwertyPlug() {qRegisterMetaType<qwerty *>("qwerty""*");} QByteArray name() {return "qwerty";} };

and it looks ok (sorry for the readability but I dont know how to add newlines..) and works if copy/paste the above line in my code but...

When I compile my project I get errors from the moc:

Error: Class declaration lacks Q_OBJECT macro.

Do anyone have an idea?

bibi
  • 3,671
  • 5
  • 34
  • 50

2 Answers2

1

It turns out that as suggested by @Silicomancer you cannot as it is.

I figured out that the proble was the multi-line macro and it works indeed if the macro is one-line:

#define MY_PLUGIN_BASE(__c_name,__appendix) class __c_name##__appendix : public QObject, myPlug { Q_OBJECT Q_INTERFACES(nPanPlug) Q_PLUGIN_METADATA(IID "org.myapp.plug") public: __c_name##__appendix() {qRegisterMetaType<__c_name *>(#__c_name"*");} QByteArray name() {return #__c_name;} };

To me it looks like moc goes through the file looking for Q_OBJECT but doesn't mess with macros

bibi
  • 3,671
  • 5
  • 34
  • 50
  • 2
    Seems like moc can be fooled easily. Still I am not sure if you should do it that way. If your code changes it could break any time again. Consider droping that macro approach or find you own way of preprocessing. – Silicomancer Dec 09 '16 at 13:42
0

There is an easy alternative solution. You can define your macro like this:

#define MY_MACRO(qobj, PARAM1, PARAM2, ETC)
...
... // (do your macro here, but don't use the first param, qobj)
...

When you call the macro in your header file, call it like this

MY_MACRO(Q_OBJECT, 1, 2, 3)

This will trick the MOC to running on your header file, because it's dumb and just sees the string Q_OBJECT.

user2522165
  • 73
  • 1
  • 1
  • 6