Link to home
Start Free TrialLog in
Avatar of anAppBuilder
anAppBuilderFlag for United States of America

asked on

Compiling websocketpp with MySQL in Windows

I am experimenting with websocketpp in VisualStudio C++ 2010 Express.  I have a working test websocketpp server talking to a browser.  Now I want to add a MySQL back end.  When I try to compile websocketpp with MySQL it breaks.  The [first] error is:

...\websocketpp\websocketpp-master\websocketpp-master\src\http\parser.hpp(46): error C2059: syntax error : 'string'

I'll include the source for parser.hpp.  Line 46 is the VERSION line below
    namespace state {
        enum value {
            METHOD,
            RESOURCE,
            VERSION,
            HEADERS
        };
    }

Open in new window

Everything else compiles together before I add MySQL and MySQL compiles with everything else if I don't have websocketpp in there.

How do I get it all to build together?

Thanks!
parser.hpp.txt
ASKER CERTIFIED SOLUTION
Avatar of ambience
ambience
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of anAppBuilder

ASKER

Thank you, Ambien.

When I right click on VERSION I get this line
     #define VERSION "5.5.16"
in one of the MySQL .h files.

So I guess I need to dig through websocketpp and change it's VERSION to something else like WSPP_VERSION, right?.  (Probably safer there than trying to change MySQL)

I'm also getting another set of errors like this:
1>c:\program files (x86)\boost\boost_1_50\boost\thread\win32\thread_data.hpp(210): error C2146: syntax error : missing ')' before identifier 'rel_time'
       
Didn't mention this before since often many error messages are the result of one error.  But now in this case I don't think so.  So several questions:
1) Should I submit a separate question about this (after I fix the VERSION problem)?  I want to be able to give fair credit for answers.
2) If not, why is Boost OK with Websocketpp OR MySQL but not both?
Sure you can change VERSION in webscoketpp, given you have all the sources.

I dont have boost right now, so can you post the code where the error takes you?

Sometimes changing the order of includes leads to errors, so can you try like including boost before including mysql or other combinations? This may not work, but worth a try.
Thanks, again.  

Here are all the errors and the Boost header files that are indicated by the errors.
thread-data.h
thread.h
Errors.txt
Cant tell anything from these files. Line 210 does not even exist in thread-data.hpp. Must be some internal platform specific thread-data.hpp
Thanks, Ambien, I'll try to clarify.  The problem is in thread-data, the long file, not thread.

Here are the lines starting at 210:

       
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
        {
            interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
        }

Open in new window

The error occurs on the word "sleep".
To isolate the problem, I reproduced it using the websocketpp echo server.  Posting the code and the errors.
echo-server.cpp
Errors.txt
Thank you, Ambien
A few more details on the VERSION conflict:

Line 615 of my_config.h
#define VERSION "5.5.16"

Open in new window

conflicts with
line 46 of websocketpp parser.hpp
            VERSION,

Open in new window

I did a quick test by changing
#define VERSION "5.5.16"

Open in new window

to
#define MYSQL_VERSION "5.5.16" 

Open in new window

and it eliminates the VERSION errors without impacting the boost errors.  
So presumably:

1)  I can fix this error by renaming the VERSION in websocketpp and recompiling everything (I'd rather not try to recompile MySQL).  I'll post anything I learn by doing this.

2) The boost errors are probably an independent problem

I'll continue to seek a solution to the boost errors.
Do you get boost errors without mysql? The following errors dont make much sense except possibly that the code is messed up (could well be another macro).

1>c:\program files (x86)\boost\boost_1_50\boost\thread\win32\thread_data.hpp(210): error C2065: 'rel_time' : undeclared identifier
1>c:\program files (x86)\boost\boost_1_50\boost\thread\win32\thread_data.hpp(210): error C2182: 'Sleep' : illegal use of type 'void'


In this line

inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)

can you check whether BOOST_... and TimeDuration are macros? Where does goto definition take you? The former should be a macro.
Thank you, Ambien.  It's very gracious of you to continue helping me; should I open a new question for this?

There are no boost errors without MySQL.  Or WITH MySQL WITHOUT websocketpp.  But I think websocketpp is causing additional Boost libs to be brought in.

BOOST_SYMBOL_VISIBLE is a macro defined in
C:\Program Files (x86)\boost\boost_1_51\boost\config\suffix.hpp by this code:
// ensure that visibility macros are always defined, thus symplifying use
//
#ifndef BOOST_SYMBOL_EXPORT
# define BOOST_SYMBOL_EXPORT
#endif
#ifndef BOOST_SYMBOL_IMPORT
# define BOOST_SYMBOL_IMPORT
#endif
#ifndef BOOST_SYMBOL_VISIBLE
# define BOOST_SYMBOL_VISIBLE
#endif

Open in new window

TimeDuration  is a template parameter.  Here's a bigger snippet:
 template<typename TimeDuration>
        inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
        {
            interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
        }
        inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)
        {
            interruptible_wait(abs_time);
        }

Open in new window

But here's the big ugly.  sleep is a macro!  And its definition goes to a MySQL file ...\mysql\mysql5.5.16\include\my_global.h
#define sleep(a) Sleep((a)*1000)

Open in new window

Well that nails down WHAT is happening.  Not sure what to do about it.  It doesn't seem very feasible to start editing and rebuilding either MySQL or the boost libs.  Any ideas?
Unfortunately macros bleed through namespaces so theres really no way around except to shield the rest of code from them.

I would recommend that you create your own wrappers around mySQL functionality (a facade on top of it). Think of it like what you'd be doing if you had to support multiple databases?

For example (and since I have no idea of your existing code or mysql code).

You can have a class say

Database.hpp

// define Database class

class Database
{
public:
virtual void executeSQL(const std::string& sql) = 0;
};

// Database.mysql.hpp

class MySQLAPI;
class MySqlDatabase : Database
{
public:
virtual void executeSQL(const std::string& sql);

private:
MySQLDatabaseImpl* _impl;  // the pImpl pattern
};

// Database.mysql.cpp

#include <all bad mysql stuff here and only here>

class MySQLDatabaseImpl
{
// data and methods to work with mysql
};

void MySqlDatabase::executeSQL(const std::string& sql)
{
         _impl-> executeSQL(sql);
}

This is just a crude and rough design, but the important point is that all mysql specific API is hidden by using a pImpl pattern and no mySQL specific code can bleed into the main code. Note that I have used pImpl but also a facade where you can have different implementations of the Database, but if you want you can trim that part.
Thank you again ambience.  I've spent several hours reading about the pImpl pattern and am trying to work through implementing it.  When I get here:

void MySqlDatabase::executeSQL(const std::string& sql)
{
         _impl-> executeSQL(sql);
}

I get an error in this line          _impl-> executeSQL(sql);

<error type> * MySqlDatabase:_impl
Error: Expression must have Pointer-to-Class type

So I added this line above it declaring the pointer
    MySqlDatabase* _impl;

I now get these compile errors:

1>  MySqlDatabase.cpp
1>d:\users\MyComputer\documents\visual studio 2010\projects\MyProject\websocketpptest3\websocketstest1\mysqldatabase.hpp(12): error C2143: syntax error : missing ';' before '*'
1>d:\users\MyComputer\documents\visual studio 2010\projects\MyProject\websocketpptest3\websocketstest1\mysqldatabase.hpp(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\users\MyComputer\documents\visual studio 2010\projects\MyProject\websocketpptest3\websocketstest1\mysqldatabase.hpp(12): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>  DatabaseWrapper.hpp
1>  Generating Code...
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
Can you post all the code for the wrapper? (the hpp and cpp)

It looks like you might not have defined all the needed classes.
Thank you again....Here they all are.  Had to rename the .hpp to .h to make the Expert exchange attachment tool accept them.

Note that there is not any code at the moment that actually CALLs any MySQL.  I pared it down to the minimum code to reproduce the errors.  Once that compiles i'll add back my functions that call MySQL.
DatabaseWrapper.h
MySqlDatabase.h
MySqlDatabase.cpp
echo-server-PlusIncludes.cpp
See if these work

///////////////

// MySqlDatabase.hpp

#include "DatabaseWrapper.hpp"
#include <string>

#ifndef MySqlDatabase_HEADER
#define MySqlDatabase_HEADER

class MySqlDatabaseImpl;
class MySqlDatabase : DatabaseWrapper
{
public:
      MySqlDatabase();
      virtual void executeSQL(const std::string& sql);

private:
      std::auto_ptr<MySqlDatabaseImpl> _impl;  // the pImpl pattern
};

#endif

///////////////////////////////

// MySqlDatabase.cpp

//#include <all bad mysql stuff here and only here>

#include "MySqlDatabase.hpp"
#include <string>
#include <my_global.h>
#include <mysql.h>

class MySqlDatabaseImpl
{
public:
      void executeSQL(const std::string& sql);
};

MySqlDatabase::MySqlDatabase()
      : _impl(new MySqlDatabaseImpl())
{
}

void MySqlDatabase::executeSQL(const std::string& sql)
{
      _impl -> executeSQL(sql);
}
Thank you again. Much closer.  Still one error though

1>MySqlDatabase.obj : error LNK2019: unresolved external symbol "public: void __thiscall MySqlDatabaseImpl::executeSQL(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?executeSQL@MySqlDatabaseImpl@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "public: virtual void __thiscall MySqlDatabase::executeSQL(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?executeSQL@MySqlDatabase@@UAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>D:\Users\MyComputer\Documents\Visual Studio 2010\Projects\MyProject\WebsocketppTest3\Debug\WebsocketppTest3.exe : fatal error LNK1120: 1 unresolved externals2010\Projects\EasyProfit\WebsocketppTest3\Debug\WebsocketppTest3.exe : fatal error LNK1120: 1 unresolved externals
This is because this class

class MySqlDatabaseImpl
{
public:
      void executeSQL(const std::string& sql);
};

is unimplemented. You have to implement here code that would let you use mySQL. Please note that I only gave a skeleton of what should solve the macro conflicts. This is by no means a finished job as you'll have to add methods and data here depending upon your needs of working with mySQL.

For the time being adding

void MySqlDatabaseImpl::executeSQL(const std::string& sql) {
}

should fix the linker errors.
Thank you very much.  I understand that there is still a lot of work to do.  I now have a working skeleton.  You have been a HUGE help.