PDA

View Full Version : #ifndef syntax error



cbeall1
13th February 2006, 20:43
I'm still working on subclassing an external library, and have decided to use preprocessor directives to set my .h file up so the library will work with or without Qt.

For compiling my library without Qt I define a compiler flag -DNOQT.

In my .h file I put



#ifndef NOQT
class Server: public QObject{
Q_OBJECT
#else
class Server{
#endif

I can compile this just fine without Qt. But with Qt I get the following errror:
Error: syntax error

When I try the following it works. But of course then I can't compile the library without Qt:


#ifndef NOQT
class Server: public QObject{
Q_OBJECT
//#else
//class Server{
#endif

Any ideas on fixing this? It would be really great if I could maintain just one .h file.

Codepoet
13th February 2006, 21:04
I can't see anything wrong but I have a workaround:


#ifndef NOQT
class Server: public QObject{
#else
#undef Q_OBJECT
class Server{
#endif
Q_OBJECT

If the error persists please post more code.

cbeall1
13th February 2006, 21:15
When I do that I get

../my_sockets/my_sockets.h:46: Warning: Cannot use Q_OBJECT in nested class.
../my_sockets/my_sockets.h:78: Error: syntax error
make: *** [.moc/moc_my_sockets.cpp] Error 1

Below is my complete header file, just in case you see something else that may cause this. I had a few more #ifndef statements, but commented them out to make sure that the one I'm looking at is really the offending one.


#ifndef MYSOCKETS_H
#define MYSOCKETS_H

#include "rbTree.h"
#include "Fields.h"

// just for file testing
#include <iostream>
#include <fstream>
//#include <csignal>

//#ifndef NOQT
#include <qframe.h>
#include <qobject.h>
//#endif


using namespace std;

// global methods
void* server_thread_stub(void*);
void* server_rcv_thread_stub(void*);
void* client_rcv_thread_stub(void*);


typedef struct position{
int lateral;
int distance;
int vertical;
};

typedef struct client_info{
int fd;
bool master;
char ip[20];
char name[100];
int video;
};

#ifndef NOQT
class Server: public QObject{
Q_OBJECT
#else
class Server{
#endif

public:
Server(int);
virtual ~Server();
int server_thread(void);
int getImage();
// client functions
int connectClient(int);
int send();
int sendImage(char *);
friend int receive_message(int);
friend void* server_rcv_thread_stub(void*);
friend void* client_rcv_thread_stub(void*);
rbTree<int> client_tree;

//Server( QObject *parent=0, const char *name=0 );
//#ifndef NOQT
signals:
void updateClientList();
//#endif

private:
static unsigned long int tid;

int port;
int newsockfd;
int newClientsockfd;

};

#endif //MYSOCKETS_H

michel
13th February 2006, 21:55
Probably moc is not liking this. Why not just make two complete but separate versions of the class and put your #ifndef-else statement entirely around the one using QT instead of just the first two lines? I think that way moc would be happier and it's not like at compile time the second class is created anyway.

Codepoet
13th February 2006, 22:15
As usual, macros are evil...

Maybe we can find a better way to do this: Everything in your library should work without Qt. Then create thin wrapper classes for Qt which derive from QObject and the particular class. That way you can avoid those macros.

cbeall1
13th February 2006, 22:43
I was able to get it to work by putting two separate class declarations inside the #ifndef #else statements. This solution is acceptable, especially since I don't have much time.

Although I gave Codepoet's idea a quick try, since this would certainly be more elegant. But the problem is that I do have an #ifndef statement inside my cpp code so that I can emit a Qt signal. If I set my classes up so that the "Qt-enabled" server class inherits from the "Qt-ignorant" class, it complains about the emit signal in the cpp code not being defined in the base class. And there is no easy way around this. So I'll go with the first approach.

Codepoet
14th February 2006, 10:29
Although I gave Codepoet's idea a quick try, since this would certainly be more elegant. But the problem is that I do have an #ifndef statement inside my cpp code so that I can emit a Qt signal. If I set my classes up so that the "Qt-enabled" server class inherits from the "Qt-ignorant" class, it complains about the emit signal in the cpp code not being defined in the base class. And there is no easy way around this. So I'll go with the first approach.
For the next time: You can instead call a protected virtual member function which does nothing in the base class and in the Qt class you can override this method to call emit ;)