0

Recently, I was learning about networking in C++ and I found boost.asio which is a cross platform library, and then I got a thought about how this library is a cross platform since Windows provides different library for networking and even mac also, so how its function works on different machines, does cross platform libraries create their own functions for this purpose or they contain different private functions of different machine's logics and provides public functions which then during compiling time check for on which machine that codes are compiling and change our written functions with machines defined libraries.

For example

//Operations for windows
Private void WindowsFunc 
{ code } 

//Operations for mac
Private void MacFunc
{ code }

//library's functions
Public void Do
{
    //Performs different operations
    //for different machines

    If (windows)
        WindowsFunc
    else if (Mac)
        MacFunc
}

It could be a solution may be

Cahit Gungor
  • 1,477
  • 23
  • 30

3 Answers3

1

This is often done using compiler-specific macros. For example, the gcc compiler defines the preprocessor symbol

__linux

on Linux. So, C or C++ code can use

#if __linux

to compile Linux-specific code. Nothing in the actual code actually #defines this. This is defined by default, by the Linux version of gcc. Similar preprocessor macros are defined on other platforms support by gcc. Other compilers have similar pre-defined macros. Cross-platform library's sources assemble a collection of these macros they check in order to compile operating system-specific code.

Another, common approach is to explicitly define a library-specific symbol as part of the library's build instruction or script. The build instructions that come with a cross-platform library include the instructions for running the appropriate script, from the library's package, that runs the compiler and explicitly sets the appropriate preprocessor symbol, which is then used in this manner.

Generally, preprocessor usage is discouraged in modern C++ code, and used sparingly. This is one use case where preprocessor macro usage is quite common, in practice.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
1

There are several possible ways:

  1. Use ifdefs
char* doFoo(void){
#ifdef _WIN32
  return "win32";
#elif ...
  return ...;
#endif ...
}

The pro is, that it doesn't require much setup.

The con is, that it clutters the code, if you do it too much.

  1. Have different implementations in different directories.

As a folder structure:

root
|---->Other files
|---->windows implementation
|   |->foo.c
|---->linux implementation
    |->foo.c
|---->macos implementation
    |->foo.c

And then you can use some build system, or a custom shell script for selecting things.

(Pseudo code)

if(OS==windows)
  compileDirectory(windowsImpl);
else if(OS==linux)
  compileDirectory(windowsImpl);
if(OS==macos)
  compileDirectory(windowsImpl);

The pro is, that it doesn't clutter the code, allows better adding of new features and some sort of abstraction.

The contra is, that it can be quite tremendeous to setup.

JCWasmx86
  • 3,473
  • 2
  • 11
  • 29
1

Generally cross platform libraries are implemented in layers.

There is the public interface, the common code, and a minimalized set of platform dependent code.

The public interface usually uses #if defined(symbol) checks to determine which platform it is running on. It may include system headers based on this, but more often will simply forward declare any symbols it needs to expose for platform specific APIs (if any). In some cases, header only libraries will go further than this.

The common code will have minimal platform specific stuff in it. It will try to deal with platform specific stuff using abstraction; it may #include platform specific helper headers, but the code is common between platforms.

Like, it might use Native::RWLock and Native::RWLock::lock( mutex ) functions that are typedefs and thin wrappers around platform specific types.

The platform specific code is different for each platform. It may be conditionally compiled in the build system NativeMutexImp_mac.cpp , or wrapped in #ifdef blocks, or even both.

Now header only libraries are leakier than this. And some less organized cross platform code will mix thenplatform specific and not code all over the place. Finally, performance requirements may require some leaking platform specific code in public header files.

But the main idea is that you hide the OS API use that you in turn use to implement your cross platform functionality.

This can make the end user code faster than native OS API use if your API makes efficient use easier than the native APIs do. Optimization is fungible; code that is easier to make performant is actually faster in practice.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524