Estoy desarrollando un programa en c ++ / Qt que tendrá varios complementos. Para cada clase, tengo que definir una interfaz de complemento que se vea así:

//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";} 
};

Creé una macro (en realidad 2 ya que no soy un gurú del preprocesador de c ++):

#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)

De modo que en mi código (donde se define qwerty) solo tengo que agregar:

MY_PLUGIN(qwerty)

Que se expandirá (salida de 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";} };

Y se ve bien (lo siento por la legibilidad pero no sé cómo agregar nuevas líneas ..) y funciona si copia / pega la línea anterior en mi código pero ...

Cuando compilo mi proyecto, obtengo errores de moc:

Error: Class declaration lacks Q_OBJECT macro.

¿Alguien tiene una idea?

2
bibi 9 dic. 2016 a las 12:20
¿Qué es myPlug?
 – 
Silicomancer
9 dic. 2016 a las 13:36
Esa es la interfaz del complemento, la que define el instantiate y tiene Q_DECLARE_INTERFACE(myPlug, "org.myapp.plug")
 – 
bibi
9 dic. 2016 a las 14:11

1 respuesta

La mejor respuesta

Resulta que, como sugirió @Silicomancer, no puedes como está.

Descubrí que el problema era la macro de varias líneas y, de hecho, funciona si la macro es de una línea:

#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;} };

Para mí, parece que moc revisa el archivo en busca de Q_OBJECT pero no interfiere con las macros.

1
bibi 9 dic. 2016 a las 16:21
2
Parece que se puede engañar a moc fácilmente. Aún así, no estoy seguro de si debería hacerlo de esa manera. Si su código cambia, podría romperse nuevamente en cualquier momento. Considere abandonar ese enfoque macro o busque su propia forma de preprocesamiento.
 – 
Silicomancer
9 dic. 2016 a las 16:42