avoiding conflicts in macro while using thirdparty c++ libraries - c++

I am trying to use Casablanca, http server. to do so, I need to include headers files from Casablanca, which contains few macro and typedef that cause issues in my project.
so my file look like this.
simplehttpserver.h
#include "cpprest/json.h"
#include "cpprest/http_listener.h"
#include "cpprest/uri.h"
#include "cpprest/asyncrt_utils.h"
SimpleHttpServer {
SimpleHttpServer(utility::string_t, std::function<void(http_request)> &request_handler);
void OnInitialize();
void StartServer();
void StopServer();
private:
std::unique_ptr<http_listener> m_listenerUptr;
// Handlers
std::function<void(http::http_request)> m_all_requests;
pplx::task<void> open() { return m_listenerUptr->open(); }
pplx::task<void> close() { return m_listenerUptr->close(); }
// SimpleHttpServer http_server_;
utility::string_t address_;
}
Say in my original code where I want to include this.
#include "simplehttpserver.h"
this causes all Casablanca header files pre-compiled into my project which conflicts with macros and typedef in my project.
e.g. __declspec
I don't want to change my macros cause that will be lot of code change. and I don't want to change Casablanca header files, cause that will also cause long term maintenance overhead.
I am sure, this must be very common problem in c++, can someone please help me how can resolve this.
thanks in advance.

Related

Why is a "user breakpoint" called when I run my project with imported .lib, not when code is inline?

The Situation
I am writing a wrapper library for GPIB communications for setting up specific instruments according to a clients specifications to automate some of their processes. I have to use C++ and the old '98 compiler in VC++ 6.0 running on a Windows NT machine to maintain compatibility with some other devices they use regularly.
I am trying to make a class that combines some GPIB commands into easier to remember functions, while also keeping the capability of directly communicating with the instruments. To that end, I have compiled different parts of my project into different libs and dlls, each dll being a different device that they might want to communicate with. I also made a generic dll base class from which all the specific instrument classes inherit, hopefully making the whole setup as modular as possible.
The Problem
So, with all that said, I have an issue when I try to test the different dlls/modules. I created a project to test the generic base class, added the .lib file to the project, which links to the .dll, and also #included the header file for that dll. testGeneric.cpp looks like this:
#include "GENERIC.h"
void main(void) {
GPIBInstrument hp(2); //connects to device at primary address #2
hp.write("*IDN?");
}
Super simple. To be clear, I also have the GENERIC.lib linked in the "Resource Files" folder in VC++ 6.0, and I have GENERIC.dll accessible from the path variable.
Moving on, GENERIC.h looks like this (select parts):
#ifndef GENERIC_H
#define GENERIC_H
#include <string>
#include <windows.h>
#include "decl-32.h"
#ifdef GENERIC_EXPORT
#define GENERIC_API __declspec(dllexport)
#else
#define GENERIC_API __declspec(dllimport)
#endif
...(Inline exception classes)...
class GENERIC_API GPIBInstrument {
...
public:
void write(std::string command);
...
};
#endif
Just showing the relevant methods. Then GENERIC.cpp:
#define GENERIC_EXPORT
#include "GENERIC.h"
...
void GPIBInstrument::write(std::string command) {
ibwrt (handle, &command[0u], command.length());
std::cout << command << std::endl;
if (ibsta & TIMO) {
timeoutError();
}
if (ibsta & ERR) {
error("Unable to write command to instrument: " + command);
}
}
So, looks pretty good right? No issues. Compiles fine. I try running it, and BLAM! I get this: "User breakpoint called from code at 0x77f7645c". So, then I thought, well maybe it would work if I put all the code from GENERIC.h and GENERIC.cpp into one file, and #included that file all as inline code. So I tried it, and it and it compiled nicely, and ran fine.
Question (<-AHA!... But...)
What am I doing wrong!? Something with the way I'm making the .dll? Or the .lib? Or something else entirely?
EDIT (WHY!?)
So, after a bit of debugging, I found that it was something to do with passing a string literal. So I just modified it to:
std::string command = "*IDN?";
hp.write(command);
and it worked fine. My followup question, is why? What's the difference between having a string literal passed, versus assigning that to a variable and then passing it in?
Using complex types such as std::string as a parameter at a DLL boundary is tricky. You must ensure that the exe and the DLL use the exact same instance of the library code. This requires that you build them both to use the same version of the DLL version of the runtime library.

Hiding use of class inside a library

I am creating a simple library for Arduino, the intent of which is to wrap and hide another class inside of it. I would like to be able to hide the underlying class entirely from the end user.
I have somewhat simplified this example to keep things clear, but the same problem exists.
The class I am trying to wrap is the Wire library which is called TwoWire.
The header file of the wrapper library:
#ifndef __DERIVEDONEWIRE2_H__
#define __DERIVEDONEWIRE2_H__
#include <Wire.h>
class DerivedWire
{
private:
TwoWire wire;
public:
DerivedWire();
};
#endif
The CPP file:
#include "DerivedWire.h"
DerivedWire::DerivedWire()
{
}
And the Arduino sketch that uses it:
#include <DerivedWire.h>
DerivedWire derivedWire;
void setup()
{
}
void loop()
{
}
This fails to compile:
/Users/andrew/Documents/Arduino/libraries/DerivedWire/DerivedWire.h:9:
error: 'TwoWire' does not name a type
Including Wire.h at the top of the main sketch allows this to compile:
#include <DerivedWire.h>
#include <Wire.h>
DerivedWire derivedWire;
void setup()
{
}
void loop()
{
}
However I would like to completely hide from the user of the DerivedWire library that the Wire library/TwoWire class is used at all.
I have tried changing the line "TwoWire wire;" to "TwoWire* wire;" - now I get the following error:
/Users/andrew/Documents/Arduino/libraries/DerivedWire/DerivedWire.h:9:
error: ISO C++ forbids declaration of 'TwoWire' with no type
/Users/andrew/Documents/Arduino/libraries/DerivedWire/DerivedWire.h:9:
error: expected ';' before '*' token
I've tried a few other things, but it just seems that I need to include Wire.h at the top level.
How do I fix this?
The Wire instance is created on the last line in the lib.
https://github.com/lstoll/arduino-libraries/blob/master/Wire/Wire.cpp
You are NOT supposed to have multiple instances of TwoWire, and there is no reason to hide it, but if you really want to hide it, you have to remove that line.
The arduino build method requires that the lib is included from the main sketch so you can not hide that part without signifigant changes.
If you really really need to hide this Wire instance, you could copy the source of the Wire lib into your own lib, and remove that last line.
Check out the "pimpl idiom", here's a link to get you started: http://en.wikipedia.org/wiki/Opaque_pointer
Pimpl idiom is a way in C++ to hide a class implementation, and all functions that you do not want to be visible.

C/C++ namespace in header issue

I am trying to implement a Websocket Server. I am using the libwebsockets library.
ConnectionServer.c file has setup code for the library and main() function (I don't see anything of importance to post here.) This file includes 1 file for the received data callback called:
dmserver_callback.cpp.
This file then includes another file (my custom parser file) called:
data_parser.cpp.
This file then includes a file called definitions.h (the source of the problem).
Just bear with me; I understand that including files (daisy chaining; so to speak) probably isn't the best way to do this, and I more than likely should be using header files and such. One question I have is that is this particularly necessary?
To clarify, everything is working as intended until I try to add my own parsing mechanism.
The definitions.h file is as follows:
namespace EngineDefinitions {
enum Version {
Major = 1,
Minor = 2
}; //Version;
namespace Server {
enum enum_Server {
MAX_PLAYERS = 200,
MAX_TABLES = 42, // 3 tables per row.
MAX_TABLE_PLAYERS = 10,
GAME_PORT = 2040, //2042
MAX_PARAMS = 10
}; //Server;
};
namespace Login {
enum enum_Login {
USERNAME = 1,
PASSWORD = 2
}; //Login;
};
};
My error is:
definitions.h(1): error C2061: syntax error : identifier 'EngineDefinitions'
I loaded the exact same header in a new Win32 Console Project in Visual C++ 2010 Express and there it works. The only difference I see is the main file (where int main function resides).
In the project that the header file works is called:
ConectionServer.cpp (C++)
and the main project file that doesn't work is named:
ConnectionServer.c (C)
Does this have something to do with the file being compiled in C vs C++?
I think that the libwebsocket library is coded in C.
I can't recall if I created the project files in exactly the same manner or not.
P.S. Please let me know if there is any other information I can provide to help.
EDIT: I also realize you're not supposed to define types inside a header file (eg: enums).
I DID try to separate the source into .cpp and a header file using the extern enum
with no difference. In fact, got more errors (redefinitions) than I bargained for when trying to use them.
You need to understand that C++ and C are different languages. When you include the header file in a .cpp file, the compiler will try to compile the .h as C++ code. C++ supports namespaces, so everyone is happy. But when you try to include the .h from the .c file (which is what is actually happening if you follow the #includes), the compiler attempts to compile the .h as C code, yet fails because namespaces do not exist in C.
A common way to solve this problem is to use predefined macros. __cplusplus is defined when compiling as C++ code, and not defined when compiling as C code (obviously).
You could do this:
#ifdef __cplusplus
namespace EngineDefinitions {
#endif
enum Version {
Major = 1,
Minor = 2
}; //Version;
#ifdef __cplusplus
namespace Server {
#endif
enum enum_Server {
MAX_PLAYERS = 200,
MAX_TABLES = 42, // 3 tables per row.
MAX_TABLE_PLAYERS = 10,
GAME_PORT = 2040, //2042
MAX_PARAMS = 10
}; //Server;
#ifdef __cplusplus
};
#endif
#ifdef __cplusplus
namespace Login {
#endif
enum enum_Login {
USERNAME = 1,
PASSWORD = 2
}; //Login;
#ifdef __cplusplus
};
#endif
And of course, you lose the ability of namespaces in C anyways.
C does not have namespaces. For Real.
You cannot include a C++ file in a C file (unless it has been prepared for such use). If you then try to compile the C file, it'll try to compile even the C++ file as C. Instead, use separate compilation and header files.
Note that C does not understand namespaces.

Instantiating a Qt File-Based Logger for Debugging in a C++ Library

The following page provides a nice simple solution for file based logging in Qt for debugging without using a larger logging framework like the many that are suggested in other SO questions.
I'm writing a library and would like to instantiate a logger that the classes in the library can use (mostly for debugging purposes). There is no int main() function since it's a library. So would the best approach be to add the instantiation into a file like logger.h and have any classes include logger.h if it would like to do qDebug() << PREFIX << "Bla" as the link above suggests?
I pretty much agree with OrcunC but I'd recommend making that ofstream a little more accessible and capable of handling the Qt value types.
Here's my recommended process:
Create a global QIODevice that to which everything will be written. This will probably be a QFile.
Create a QTextStream wrapper around that QIODevice that you'll then use for all the logging.
If you want something slightly more complicated, create methods that do the filtering based on log level info.
For example:
// setup the global logger somewhere appropriate
QFile *file = new QFile("your.log");
file->open(QIODevice::ReadOnly);
QTextStream *qlogger = new QTextStream(file);
And once the global logger is initialized, you could reference it as a global:
#include "qlogger.h"
//... and within some method
*qlogger << "your log" << aQtValueType;
But you might want some filtering:
#include "qlogger.h"
// lower number = higher priority
void setCurrentLogLevel(int level) {
globalLogLevel = level;
}
QTextStream* qLog(int level) {
if (level <= globalLogLevel) {
return qlogger;
}
return getNullLogger(); // implementation left to reader
}
And then you'd likely create an enum that represented the LogLevel and do something like this:
#include "qlogger.h"
//...
setCurrentLogLevel(LogLevel::Warning);
*qLog(LogLevel::Debug) << "this will be filtered" << yourQMap;
*qLog(LogLevel::Critical) << "not filtered" << yourQString;
As you'd be dealing with globals, carefully consider memory management issues.
If you follow the method in that link, ALL messages of the application output with qCritical(), qDebug(), qFatal() and qWarning() will flow into your handler.
So be careful! You may get not only your library's trace messages but the entire QT framework's messages. I guess this is not what you really want.
Instead of this
as a simple solution define a global *ofstream* in your library and use it only within your library.
whenever you write a library in c++ or c , it is best practice to declare all your methods in a .h file and define the methods/classes in a .cpp/.c file. This serves 2 purposes.
The .h file needs to be used to compile a 3rd party application that is using your library, and the library itself is used at link time.
The developer who is using your library can use the .h file as a reference to your library since it contains all the declarations.
So ,yes , you need to declare methods in a .h file and have other classes include logger.h.

Python SIP expose function

I'm writing a Python module for some C++ code using SIP. However whilst I can easily expose classes, I cannot find a way to expose standalone functions.
Here is my header file defining the functions that I wish to expose to Python: ProxySettings.h
#include <Windows.h>
#include <Wininet.h>
bool SetConnectionOptions(const char * proxy_full_addr);
bool DisableConnectionProxy();
And here is my attempt at my SIP file so far: ProxySettings.sip. Currently running sip.exe generates C++ code with no problems, but when I come to compile it, the compiler complains about missing identifiers SetConnectionOptions and DisableConnectionProxy.
%Module ieproxy 0
bool SetConnectionOptions(const char * proxy_full_addr);
bool DisableConnectionProxy();
I think that I have to use a directive to include the ProxySettings.h header file into my SIP file, but I am not sure what directive to use. %TypeHeaderCode which is what you use for a class doesn't work with just a function.
Does anyone have any suggestions?
Try this:
%Module ieproxy 0
%UnitCode
#include <ProxySettings.h>
%End
bool SetConnectionOptions(const char * proxy_full_addr);
bool DisableConnectionProxy();