John Paul Coder
John Paul Coder

Reputation: 313

How to move code written using #ifdef to support multiple platforms into a library function?

We have a C++ project that is supporting multiple platforms (windows, linux, and mac).

To support multiple platforms, we have the below code snippet to close an existing socket for all the platforms.

#ifdef _WIN32
       closesocket(m_nSocketHandle);
#elif __APPLE__
      close(m_nSocketHandle);
#elif __linux__
        shutdown(m_nSocketHandle,SHUT_RDWR);
#endif

Similarly we are using other APIs for eg mkdir for different OS:

#ifdef _WIN32
        if (0 == _mkdir(m_hStrDirectoryPath.c_str()))
#else
    #ifdef __linux
            char mkcmd[500];
            sprintf(mkcmd, "mkdir -p %s", SDK_PATH);
            system(mkcmd);
             if (0 == mkdir(m_hStrDirectoryPath.c_str(), 0777))

    #else
            if (0 == mkdir(m_hStrDirectoryPath.c_str(), 0777))
    #endif
#endif

Instead of writing the code like this for all platforms or operating systems can we write a library (for eg., commonlib) by using the above code in the below function:

for eg.,

close_socket()
{
#ifdef _WIN32
      closesocket(m_nSocketHandle);
#elif __APPLE__
      close(m_nSocketHandle);
#elif __linux__
        shutdown(m_nSocketHandle,SHUT_RDWR);
#endif
} 

And call this function from the main application. is this possible?

Can someone provide a sample to understand this?

Upvotes: 1

Views: 435

Answers (1)

eerorika
eerorika

Reputation: 238411

is this possible?

Yes, this is possible.

What you have written is exactly how cross platform libraries are written.

Some people prefer to not have ifdefs inside function definitions. An approach that avoids that is to use separate translations units for implementations on separate systems:

// win32.cpp
close_socket()
{
      closesocket(m_nSocketHandle);
} 

// apple.cpp
close_socket()
{
      close(m_nSocketHandle);
}


// linux.cpp
close_socket()
{
      shutdown(m_nSocketHandle,SHUT_RDWR);
}

and choose the source file to compile based on target system. This approach is not an option for templates or other inline functions. Choice between the approaches is subjective.

P.S. If you need different representation of state across systems, you can use PIMPL pattern to hide the system specific data.

Upvotes: 1

Related Questions