bibi
bibi

Reputation: 3765

c++ macro containing Q_OBJECT

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?

Upvotes: 2

Views: 1378

Answers (2)

user2522165
user2522165

Reputation: 113

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.

Upvotes: 1

bibi
bibi

Reputation: 3765

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

Upvotes: 1

Related Questions