I'm creating a program and I want it to run on Windows and UNIX. However I've used many functions that are either Windows or Unix specific. For example functions located in #include<unistd.h> and #include <sys/utsname.h> for UNIX and #include <winsock2.h>and #include <windows.h>for Windows. I've got them working independently but I want to merge them together.
Here is an example:
struct timespec start, end; // UNIX code
LARGE_INTEGER clockFrequency; // Windows code
QueryPerformanceFrequency(&clockFrequency);
LARGE_INTEGER startTime;
LARGE_INTEGER endTime;
LARGE_INTEGER elapsedTime;
//...
QueryPerformanceCounter(&startTime); // Windows code
clock_gettime(CLOCK_REALTIME, &start); // UNIX code
CalculateVectorInputs();
QueryPerformanceCounter(&endTime); // Windows code
clock_gettime(CLOCK_REALTIME, &end); // UNIX code
I'm well aware of ifdef:
#ifdef _WIN32
// Windows code
#else
#ifdef __unix__
// UNIX code
#endif
#endif
but this seems very messy to add all throughout my code, seeing as my program is around 500 lines long. Is there an elegant way to approach this?
-
You could create a Windows and a Linux header file with wrappers for these functions that would carry the same name, that way you only have a single ifdef and you don't need to have them everywhere?Qubit– Qubit2018年08月28日 11:46:52 +00:00Commented Aug 28, 2018 at 11:46
-
1You need to learn about abstractions and interfaces. For example, you could put the Windows-specific code in a library, and the Unix-specific code in another library, both of them having the same interface (public functions). Then on Windows build the Windows-only library and link with it, and the same for Unix platforms with the Unix-only library.Some programmer dude– Some programmer dude2018年08月28日 11:47:32 +00:00Commented Aug 28, 2018 at 11:47
1 Answer 1
A fairly common approach is to write your main application in standard C wherever possible and put all platform specific code in a custom module.
For example, your main application could do
#include "foo_timer.h"
...
foo_timer_t start, end;
foo_get_time(&start);
calculate_stuff();
foo_get_time(&end);
foo_time_delta(start, end, &elapsed);
with no #ifdefs at all.
foo_timer.h might make use of #ifdef to select platform specific typedefs and declarations, but the main implementation will be in separate files:
foo_timer_unix.ccontains unix-specific code that implements thefoo_timer.hinterface.foo_timer_windows.ccontains windows-specific code that implements thefoo_timer.hinterface.
When your application is compiled, only one of foo_timer_unix.c and foo_timer_windows.c is compiled and linked into the application. The details of this step depend on your build system.