Solved

Compiling websocketpp with MySQL in Windows

Posted on 2013-01-22
20
779 Views
Last Modified: 2013-01-26
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
0
Comment
Question by:anAppBuilder
  • 12
  • 8
20 Comments
 
LVL 22

Accepted Solution

by:
ambience earned 500 total points
ID: 38809837
>> Line 46 is the VERSION line below

This could be one of the famous menaces caused by macros. Right click VERSION and Goto definition. Does that take you to a macro definition?

OR

try using different pnemonics like say

Version, Method, Resource
0
 

Author Comment

by:anAppBuilder
ID: 38812019
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?
0
 
LVL 22

Expert Comment

by:ambience
ID: 38812187
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.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:anAppBuilder
ID: 38812377
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
0
 
LVL 22

Expert Comment

by:ambience
ID: 38813777
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
0
 

Author Comment

by:anAppBuilder
ID: 38816563
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".
0
 

Author Comment

by:anAppBuilder
ID: 38816882
To isolate the problem, I reproduced it using the websocketpp echo server.  Posting the code and the errors.
echo-server.cpp
Errors.txt
0
 

Author Closing Comment

by:anAppBuilder
ID: 38817231
Thank you, Ambien
0
 

Author Comment

by:anAppBuilder
ID: 38817254
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.
0
 
LVL 22

Expert Comment

by:ambience
ID: 38820333
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.
0
 

Author Comment

by:anAppBuilder
ID: 38820570
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?
0
 
LVL 22

Expert Comment

by:ambience
ID: 38821022
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.
0
 

Author Comment

by:anAppBuilder
ID: 38821501
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 ==========
0
 
LVL 22

Expert Comment

by:ambience
ID: 38821536
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.
0
 

Author Comment

by:anAppBuilder
ID: 38821682
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
0
 
LVL 22

Expert Comment

by:ambience
ID: 38821726
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);
}
0
 

Author Comment

by:anAppBuilder
ID: 38822570
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
0
 

Author Comment

by:anAppBuilder
ID: 38822574
0
 
LVL 22

Expert Comment

by:ambience
ID: 38822617
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.
0
 

Author Comment

by:anAppBuilder
ID: 38822632
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.
0

Featured Post

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
CheckListBox usage 3 59
Trigger usage 2 69
Creating Functions in phpMyAdmin 8 18
Where are the c++ header files to use in Eclipse? 4 11
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question