Cross-platform C++: wrapping OS-specifics behind a class - c++

I'm working on a C++ project which should run on Linux and Windows 7+. This is also my first week with C++ after a very simple and short basics course some years back.
Let's say I need to access the filesystem, but as OS's have different APIs for that I need to create a wrapper class to make things consistent.
Would the following work:
Have a base class File. From file I inherit WinFile and LinuxFile, which implement the base class public methods (e.g. createFile, readFile, etc.). Then in both sub-classes I implement the public methods to map to platform specific methods (WINAPI file handling and UNIX file handling).
Then I would use a preprocessor directive to conditionally load either WinFile or LinuxFile in the main application:
int main()
{
#if defined WIN32
WinFile fileSystem;
#elif defined LINUX
LinuxFile fileSystem;
#endif
// Both of above contain the same public method API.
std::string filedata;
filedata = fileSystem.readFile(...);
...
}
My gut says that this should work, but are there any drawbacks? Will this become a maintainability problem easily? Are preprocessor directives considered "hacks" or something? I know they're used with header include guards and such, but they're compiler related logic, not application related logic.
Any other ways to achieve what I'm trying to do here?

You could define the API in a header file and move the implementation into cpp files.
Add the .cpp source files dependent on your os (or guard the .cpp files through) macros, for example:
// File.h
class File
{
public:
void open(std::string);
};
// File_impl_win.cpp (compiled when win)
void File::open(std::string)
{
// impl
}
// File_impl_lin.cpp (compiled when linux)
void File::open(std::string)
{
// impl
}
The advantage is that you don't need to distinguish between a LinuxFile and WindowsFile, you got a single api instead.
But there is an amazing crossplatform boost library for filesystem usage already, boost filesystem, which you could use.

Related

How to test C++ classes when header files contain explicit paths?

I have classes that look like this:
Header (.h):
class DatabaseX ; //forward declare
class DeepClass
{
public:
void DeepClass(DatabaseX* db);
void doStuff();
private:
DatabaseX *m_db;
};
Definition (.cpp)
#include "some/path/that/stretches/into/a/rather/deep/structure/DeepClass.h"
#include "another/somewhat/disturbing/long/path/to/somewhere/distant/DatabaseX.h"
void DeepClass::DeepClass(DatabaseX* db):m_db(db){ m_db->open() }
void DeepClass::~DeepClass(){ m_db->close(); delete m_db; }
void DeepClass::doStuff(){ // <complicated stuff here> }
Now I want a test that checks that doStuff() does the right kind of stuff.
So I write my own mock DatabaseX.
But I have a problem, my own mock database lives in the test directory, it has no place in production code, and what's worse, DatabaseX was never written to be inherited and overloaded.
It's a concrete class, and isn't anything like an interface.
So my question is, how do I write a test, with all these hard-coded include paths everywhere?
Do I for example:
create another duplicate file structure that matches the include paths, and put my mock DatabaseX there in this duplicate file structure?
Somehow rewite each cpp file before the compiler accesses it by some indirection magic or other?
Add macros to eat up the paths?
Write a python/perl/bash script to temporarily remove the include paths prior to compiling my tests?
Just include everything, accept the dependencies of DatabaseX, and just compile the real thing, and all it's dependencies and then replace at link time?
Accept defeat; don't write any tests, and bury my head in the sand.
OR ... ?
I should say there are well over a million lines of code, so changing the source code isn't an option.
Is there a very simple way to overcome this nightmare via a nice simple compiler option or other?
(Perhaps it's not relevant but I'm using Qt's QTest & QtCreator. Maybe there is some magical switch that makes all these gruesome paths go away!).
I am using GCC 4.8.5

What's the best way to write a wrapper for a C++ library, when rust-bindgen doesn't work on the original headers?

I'm trying to port a C++ library to Rust. One dependency isn't open-source, and I only have access to the header files. rust-bindgen doesn't generate valid bindings from these header files, and after searching online for a while, I came to the conclusion that I needed to write a wrapper for the aforementioned library. (This header files for this library are from https://github.com/wpilibsuite/ni-libraries, if it matters).
Because of these issues, I can't include the original header files in the wrapper's header files, but I can include the original headers in the actual cpp files.
To use classes, I've just forward-declared them, but some of these headers use typedefs and other fields inside the class as return types. There doesn't seem to be a (good) way to forward-declare or otherwise use these.
I'd like to know if my approach is correct, or if there's a better way to do this and I'm going the wrong way about this (it could be either in C++ or with rust-bindgen itself).
An example of my current setup:
closed-source.h
class Foo {
Foo* create();
int getBar();
}
wrapper.hpp
class Foo;
Foo* foo_create();
int foo_getBar();
wrapper.cpp
#include "closed-source.h"
#include "wrapper.hpp"
Foo* foo_create() {
return Foo::create();
}
int foo_getBar(Foo* self) {
return self->getBar();
}

Compiling a Header file into a DLL

I have created a function library that I want to create a DLL from and create an export library. Creating the DLL is not the problem.
The problem is that, I do not want the developer/user to look inside the header file as the code is not optimized and some of it looks a mess even though it works.
Is there anyway I can include the contents of the header file within another DLL so that the header file will then be hidden or is there a way to compile the header to Binary?
Win32, visual studio 2010, 'c/c++'.
First, remove the code from the header: just declare the functions and specify the classes (i.e. no code in there):
//header
void my_ignomous_function(int);
class my_ignomous_class {
public:
my_ignomous_class();
~my_ignomous_class();
bool my_ignomous_member(my_ignomous_class &x);
private:
// unfortunately, you have to give these details.
};
If this is not sufficient, you could use the pimpl idiom: in your class you use a pointer to an object that is used for the implementation. The advantage is that you can just declare the implementation class without any details in the header. The details are only needed in the implementation.
//header
class my_nice_class {
public:
my_nice_class()
~my_nice_class()
bool my_nice_member(my_nice_class &x);
private:
class my_horrible_secret_class *impl;
};
The other approach is to fune-tune your design, so that you've no longer anything to hide ;-)
As already mentioned you have to separate Declaration and Definition [1]
Declaration in Header (.h), export only functions the developers need [2] - no need for a .def file.
The user has to know the Declarations of the functions he is using. So he needs the header.
Definition (function body - implementation) in Source file (.cpp)
Maybe you can split it up into more header/source - pairs so that the header for the Developers solely contains the clean "interface" of your library - the exported function.
https://www.cprogramming.com/declare_vs_define.html
https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=msvc-170

Hide class implementation from its interface

I have this code for an interface of a class in a header file and its implementation in a separate source file :
First :The Header file "Gradebook.h"
#include <string>
using namespace std;
class Gradebook{
public:
Gradebook(string);
void setCoursename(string);
string getCoursename();
void displayMessage();
private:
string nameofCourse;
};
Second :The implementation "Gradebook.cpp"
#include "stdafx.h"
#include "Gradebook.h"
#include <iostream>
using namespace std;
Gradebook::Gradebook(string name){
setCoursename(name);
}
void Gradebook::setCoursename(string name){
nameofCourse = name;
}
string Gradebook::getCoursename(){
return nameofCourse;
}
void Gradebook::displayMessage(){
cout << "Display message function shows :" << getCoursename() << endl;
}
how can i link these two separate files in order to use only "Gradebook.h" in other project , and hide my implementation from the client-programmer ?
There are several answers. It would help to know why you actually want to hide the implementation. Here's the reasons why you might want to do this I can think of offhand.
Protecting trade secrets: Forget it. To be able to execute your code, the computer has to be able to run it. Effectively you can strip away comments, method names and variable names by compiling the code as a static library, even run an obfuscator over it to obscure the control flow (at the cost of slowing it down by adding unneeded jumps), but in the end the code (or the machine code generated from it) has to stay sort of readable or it couldn't be executed.
Make it easier to use your code: If you have several source files and might add more files, and you want your clients to just be able to drop in one file to get all the newest changes without having to add individual source files, compile it as a static or dynamic library. Then you can hand someone the library plus the headers and they can just use them.
You can also create an "umbrella header" that includes all the other headers. That way, clients can simply add the path to your library's includes folder to their compiler invocation/project file and include the one header, which includes all others. If you add or split up a header, you just change the umbrella to include the new headers and all projects that use it keep working.
Note that using a library will limit your clients: They can't step through your code in the debugger easily, they can't fix and compile stuff easily. If they need your code to run on a new platform, or want to use different optimization settings in the compiler, they can't just recompile it.
On the other hand if you plan to sell your library, you might want to hold on to your sources. Customers who don't care about the security of having the code if you ever go out of business can get a cheaper version of the library without the source code, you can charge them extra if they want any of the other features by making them buy a version for the new platforms that you coded for them, etc.
Prevent clients from accidentally relying on implementation details: You don't really need to do anything for this except split up your code into public and private files. Usually your implementation file is private and your headers are public, but you may have some private headers for internal classes.
Since C++ does not allow defining instance variables or methods that aren't declared in the header's class declaration like other languages do that support categories or class extensions, you may have to resort to the Private Implementation (aka 'pimpl') pattern.
What this usually means is that you declare one class that defines the public API that simply wraps a pointer to the actual class that contains the real implementation and calls through to it. It usually only has one instance variable, pimpl, which is the pointer to the other class. You simply forward-declare the private class using class Foo; and thus your clients' code doesn't know anything about the private class (unless they explicitly peek into the implementation file or private header, e.g. when fixing a bug).
Create a single-file class I mention this last because it is generally a stupid thing to do, but just in theory, you could also move the implementation file's content into the header. Then clients only need to include the header and get all the sources. This has lots of downsides, though, like making code harder to read, slowing down compile times, and requiring the client to deal with duplicate definitions of the class caused by including the file from several .cpp files. In short: Don't do it.

Exporting a visual studio c++ project for use in another project, without revealing the .cpp and .h source files

I have a visual studio project called
"TopSecretProject"
that I want to share with an anonymous developer user, without revealing any of my code, including the header files (Since my .h files include the structure of my project ant the user cannot know about it).
The user should receive:
A list of function names that he may call (depending on the permissions that the user has) and the user should be able to develop a program using these functions as black boxes.
My sealed TopSecretProject, that he cannot open.
Is this scenario possible in any way?
I tried the following solution but failed:
Exporting TopSecretProject as a static library.
Creating a new VS project for the user, and adding the .lib to the user project.
Copying all the .h files to the user's project and creating a pre compiled header file.
removing the headers (now that I have the .pch I don't need them anymore)
The pre compiled header is rebuilt in any run and thus removing my first pre built pch... I also tried to copy the pch directly from the TopSecretProject but it didn't help.
Thanks very much in advance!!
Any exported function declarations in the pre-compiled header, regardless of whether or not you want the end user to be able to call them, can be easily extracted from the pch (or the library, for that matter). You're only causing yourself headaches trying to deliver a pre-compiled header. :-)
Instead, how about creating a header file specifically for end users where the functions you want available to them are declared? The pitfall being you have to make a header file for each set of permissions (although is this more difficult than specifying the available functions for each set?)
Note, however, anyone could still look at your library's exported symbols if they wanted to try to use other features of the library.
Edit:
Regarding classes, if you really don't want to give the class declaration, you're stuck implementing some layer over the class for them to interact with. There's no getting around this. This probably means one of two paths:
One: You can declare some functions for creating, destroying, and using your classes and just pass back some good ole' void * pointers. e.g.
typedef void * MySecretClass;
MySecretClass initializeMSC( ... );
void freeMSC( MySecretClass cls );
int useMSC( MySecretClass cls, int param, ... );
Two: You can create a wrapper class that essentially does the same thing.
class MySecretClassWrapper
{
public:
MySecretClassWrapper( void );
int useClass( int param );
private:
void * mySecretClassData; // <-- actual class instantiated here
};
And the compiled definitions:
MySecretClassWrapper::MySecretClassWrapper( void ) {
mySecretClassData = reinterpret_cast<void *>(new MySecretClass);
}
int MySecretClassWrapper::useClass( int param ) {
MySecretClass * object = reinterpret_cast<MySecretClass *>(mySecretClassData);
return object ? object->useClass(param) : -1;
}
The first is a method I use when making C++ classes available to C applications. The second is the exact same idea but wrapped in a class which will be easier to use for C++ users.