C - Portable code on Windows and Unix - c

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?

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.c contains unix-specific code that implements the foo_timer.h interface.
foo_timer_windows.c contains windows-specific code that implements the foo_timer.h interface.
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.

Related

Multiplatform support, preprocesser or linking with individual libraries

I'm working on a homebrew game for the GBA, and was thinking about porting it to the PC (likely using SDL) as well.
I haven't dealt with the problem of multiplatform support before, so I don't really have any experience.
I came up with two possible ways of going about it, but both have drawbacks, and I don't know if there is a way better solution I'm missing out on.
First would use the preprocessor. A header file would be included in all files which would #define GBA, and based on whether it is defined, the appropriate headers will be included and the appropriate platform specific code will be compiled for the platform.
I would implement it something like
/* GBA definition is in platform.h */
/* Example.c */
void example()
#ifdef GBA
{
/* GBA specific implementation goes here */
}
#else
{
/* PC specific implementation goes here */
}
#endif
The drawback I see here is for a large project, this can get very messy and is frankly kind of ugly and difficult to read.
The other option I can think of is creating static libraries for each platform. Therefore the main source code for both platforms will be the same, increasing ease of simultaneous development, and when building for GBA or PC, the appropriate libraries and settings will be specified and that's it.
The obvious drawback here is that if there needs to be a change in the implementation of something in the library, if something needs to be added, or anything really regarding the library, it needs to be maintained and rebuilt constantly, along with the main actual program.
If there is a better way to approach this, what would it be?
If the ways I mentioned are the standard way of doing it, which is more common / better for long term development?
Here's what I would do [and have done]. Doing [a lot of] #ifdef/#else/#endif sequences is hard to maintain. Trust me, I've done it, until I found better ways. Below is a way I've used in the past. There are other similar approaches.
Here is the generic code:
// example.c -- generic code
#ifdef _USE_GBA_
#include <example_gba.c>
#endif
#ifdef _USE_SDL_
#include <example_sdl.c>
#endif
void
example(void)
{
// NOTE: this will get optimized using tail recursion into a jump or
// example_dep will get inlined here
example_dep();
}
Here is the GBA specific code:
// example_gba.c -- GBA specific code
static void
example_dep(void)
{
// ...
}
Here is the SDL code:
// example_sdl.c -- SDL specific code
static void
example_dep(void)
{
// ...
}

portable alternative to kbhit() and getch() and system("cls")

I need a way to use kbhit and getch functionality in a portable way. I'm currently developing a simple ascii game and I need to detect if a key is pressed. If it is I need to read it and if it isn't I need to continue without waiting for input. I would prefer not to echo it, but I won't be to picky about that. I think kbhit and getch would be great for this, BUT I'm only allowed to use fully portable code(well at least code for linux, mac and PC, not a lot of other OSes come to mind though). As I understand it the termios, curses, and conio libraries aren't fully implemented on all three OSes I need. I'm at a loss. Every solution I have found uses non-portable code. Is there someway I'm able to write portable functions for this myself? I'm currently including stdio.h, stdlib.h, and time.h. I also need a portable way to clear the screen as I'm currently using system("cls") and system("clear") which must also be changed every time I change the OS, or is the a way I could do an if-else and detect the OS the code is running on to switch between these two statements. Here is a segment of code that has these functions:
char key = ' ';
while(1)
{
system("cls");
if (_kbhit())
{
key =_getch();
printf("output: %c", key);
}
else
printf("output:");
}
This is essentially what functionality I need in my code, but I can't figure out a portable way to do it, and my teacher requires the code to work on Linux, mac, and pc using standard c and standard libraries. Please help! And no c++ please, we are using c.
EDIT: I don't think ncurses wasn't quite what I was looking for. Someone recommended I use #ifdef to implement these at compile time. I like this solution, but I need some help understanding how to do this on linux and mac as I can only test on windows with my current setup. hopefully I will soon have linux running on my other machine for testing, but OSX has a big price tag with it, so I would appreciate the help. Here's the current code:
//libraries
#include <stdio.h> //used for i/o
#include <stdlib.h> //used for clearing the screen
#include <time.h> //used to get time for random number generator
//check OS and include necessary libraries
#ifdef _WIN32
//code for Windows (32-bit and 64-bit, this part is common)
#include <conio.h>
#define CLEARSCREEN system("cls")
#define CHECKKEY _kbhit()
#define NBGETCHAR getch()
#elif __APPLE__
//code for mac
#define CLEARSCREEN system("clear")
#define CHECKKEY
#define NBGETCHAR
#elif __linux__
//code for linux
#define CLEARSCREEN system("clear")
#define CHECKKEY
#define NBGETCHAR
#else
# error "Unknown compiler"
#endif
int main()
{
char key = ' ';
while(1)
{
CLEARSCREEN;
if (CHECKKEY)
{
key=NBGETCHAR;
printf("output: %c", key);
}
else
printf("output:");
}
}
You should look into the portable ncurses library. In addition to many other tools for drawing in the terminal, it provides a keyboard interface which includes a getch() function.

Can't get different compilers to use specific header files?

I'm writing a C project for college, and I want to use the Sleep() function in my header file. The people marking it could be using Linux and I'm developing in VS2013 for Windows. I found out that Sleep() exists in two different header files depending on whether the compiler uses Windows or Linux, I've looked over the web and found suggestions to use "#ifdef" in the preprocessor. However I'm new to preprocessor work so I'm not sure what to use when there's many different suggestions out there, I'm particularly unsure as to whether these suggestions are for the same purpose as mine, so apologies if this is a common question. I've tried the following:
#ifdef _WIN32 || _WIN64
#include<windows.h>
#elif __linux
#include<unistd.h>
#else
#include<unistd.h>
#endif
This compiles fine in VS2013 but I get errors on a linux machine for Sleep() so the code I'm using doesn't seem to work outside of VS2013. Could someone explain what needs to be specified in order to get Windows and Linux to use their respective headers?
The Linux function is named sleep(), in lowercase, but the Windows one is Sleep(), with an uppercase S. And C is case-sensitive. Moreover, the Windows Sleep() takes the argument as milliseconds while the Linux alternative uses seconds.
So something like this is required:
#ifdef _WIN32 || _WIN64
#include<windows.h>
#define sleep(x) Sleep((x) * 1000)
#elif __linux
#include<unistd.h>
#else
#include<unistd.h>
#endif
Or if you prefer, you can do the other way around, but you'll have precision issues. (Consider using nanosleep() if that's an issue).

How to begin writing unit tests for a legacy Embedded C application - very tightly coupled modules?

I am currently working on a code base, that has never had any unit tests written on it. It has been written for a 16-bit Embedded processor, and I would like to start to add unit tests for all the code that I write, at a minimum and then extend this to other parts of the code.
My problem with this is, I have found that each module (.c file) at the application level, seems to be tightly coupled to other C files in the project. For any given file, this may be anywhere from 2-10 files down.
How do I start to write the unit tests?
What are the best/quick/most efficient ways to remove this tight coupling?
Also the unit tests will be run on the PC, (32 bit) and the embedded code is for a 16-bit processor. How do I ensure this is taken care of when porting the code to the PC?
Regarding #3 - making sure it is portable to PC, here's the strategy I use:
First, go through the embedded code and change any 'int' or 'unsigned long' to 'int16'
or 'uint32' (or whatever convention you choose).
Wrap the section in the embedded header where you define the types inside a condition:
#ifndef CORE_TYPE_DEFINITIONS
#define CORE_TYPE_DEFINITIONS
typedef long int16;
/*...*/
#endif
create a "PC_Types.h" file which defines the same types for the PC.
#ifdef CORE_TYPE_DEFINITIONS
#error "Core Types already defined"
#else
#define CORE_TYPE_DEFINITIONS
typedef short int16;
/*...*/
#endif
In the PC project, create a wrapper for each embedded c file, which contains the following:
#include "PC_Types.h"
#include "ModuleX.c" //the file under test
#include "TestHarness.h" //verification functions
int TestModuleXUnit1(void)
{
/* setup */
/* call Unit1(); */
/* verify post-conditions */
return result;
}
By wrapping every file, you have all the coupled functions available as needed. #including the original source file in your wrapper file allows you to drop in updates to the embedded code directly from your source control system without any modification. Adding the test functions after the included source gives the test code full access to all the module's functions, even if they don't have a public header.
I would begin by rereading Michael Feathers' Working Effectively with Legacy Code.

Compile different code on whether a function is available or not

Windows provides only GetTickCount up to Windows Vista and starting from that OS also GetTickCount64. How can I make a C program compile with calls to different functions?
How can I make a C compiler check whether a function is declared in the included header files and compile different portions of code depending on whether that particular function is available or not?
#if ??????????????????????????????
unsigned long long get_tick_count(void) { return GetTickCount64(); }
#else
unsigned long long get_tick_count(void) { return GetTickCount(); }
#endif
Looking for a working sample file not just hints.
Edit: I tried the following using gcc 3.4.5 from MinGW on a (64-bit) Windows 7 RC but it didn't help. If this is a MinGW problem, how can I work around this issue?
#include <windows.h>
#if (WINVER >= 0x0600)
unsigned long long get_tick_count(void) { return 600/*GetTickCount64()*/; }
#else
unsigned long long get_tick_count(void) { return 0/*GetTickCount()*/; }
#endif
Compile time selection of an API based on the target Windows version locks the built executable to that version and newer. This is a common technique for open source, *nix targeted projects where it is assumed that the user will configure the source kit for his platform and compile clean to install.
On Windows, this is not the usual technique because it isn't generally safe to assume that an end user will have a compiler at all, let alone want to deal with the intricacies of getting a project to build.
Often, just using the older API that is present in all versions of Windows is a sufficient answer. This is also simple: you just ignore the existence of a new API.
When that isn't sufficient, you use LoadLibrary() and GetProcAddress() to attempt to resolve the new symbol at run time. If it can't be resolved, then you fall back to the older API.
Here's a possible implementation. It detects the first call, and at attempts to load the library and resolve the name "GetTickCount64". In all calls, if the pointer to resolved symbol is non-null, it calls it and returns the result. Otherwise, it falls back on the older API, casting its return value to match the wrapper's type.
unsigned long long get_tick_count(void) {
static int first = 1;
static ULONGLONG WINAPI (*pGetTickCount64)(void);
if (first) {
HMODULE hlib = LoadLibraryA("KERNEL32.DLL");
pGetTickCount64 = GetProcAddressA(hlib, "GetTickCount64");
first = 0;
}
if (pGetTickCount64)
return pGetTickCount64();
return (unsigned long long)GetTickCount();
}
Note that I used the ...A flavors of the API functions since it is known that the library name and the symbol name will only be ASCII... if using this technique to load symbols from an installed DLL that might be in a folder named with non-ASCII characters, then you will need to worry about using a Unicode build.
This is untested, your mileage will vary, etc...
You can achieve it using preprocessor definitions in Windows headers.
unsigned long long
get_tick_count(void)
{
#if WINVER >= 0x0600
return GetTickCount64();
#else
return GetTickCount();
#endif
}
The right way to deal with this kind of problems is to check whether the function is available, but this cannot be done reliably during the project compilation. You should add a configuration stage, which details depend on your build tool, both cmake and scons, two cross platforms build tools, provide the facilities. Basically, it goes like this:
/* config.h */
#define HAVE_GETTICKSCOUNT64_FUNC
And then in your project, you do:
#include "config.h"
#ifdef HAVE_GETTICKSCOUNT64_FUNC
....
#else
...
#endif
Although it looks similar to the obvious way, it is much more maintainable in the long term. In particular, you should avoid as much as possible to depend on versions, and check for capabilities instead. Checking for versions quickly leads to complicated, interleaved conditionals, whereas with the technique above, everything is controlled from one config.h, hopefully generated automatically.
In scons and cmake, they will have tests which are run automatically to check whether the function is available, and define the variable in the config.h or not depending on the check. The fundamental idea is to decouple the capability detection/setting from your code.
Note that this can handle cases where you need to build binaries which run on different platforms (say run on XP even if built on Vista). It is just a matter of changing the config.h. If dones poperly, that's just a matter of changing the config.h (you could have a script which generate the config.h on any platform, and then gather config.h for windows xp, Vista, etc...). I don't think it is specific to unix at all.
Previous answers have pointed out checking for the particular #define that would be present for your particular case. This answer is for a more general case of compiling different code whether a function is available or not.
Rather than trying to do everything in the C file itself, this is the sort of thing where configure scripts really shine. If you were running on linux, I would point you to the GNU Autotools without hesitation. I know there's ports available for Windows, at least if you're using Cygwin or MSYS, but I have no idea how effective they are.
A simple (and very very ugly) script that could work if you have sh handy (I don't have a Windows setup handy to test this on) would look something like this:
#!/bin/sh
# First, create a .c file that tests for the existance of GetTickCount64()
cat >conftest.c <<_CONFEOF
#include <windows.h>
int main() {
GetTickCount64();
return 0;
}
_CONFEOF
# Then, try to actually compile the above .c file
gcc conftest.c -o conftest.out
# Check gcc's return value to determine if it worked.
# If it returns 0, compilation worked so set CONF_HASGETTICKCOUNT64
# If it doesn't return 0, there was an error, so probably no GetTickCount64()
if [ $? -eq 0 ]
then
confdefs='-D CONF_HASGETTICKCOUNT64=1'
fi
# Now get rid of the temporary files we made.
rm conftest.c
rm conftest.out
# And compile your real program, passing CONF_HASGETTICKCOUNT64 if it exists.
gcc $confdefs yourfile.c
This should be easy enough to translate into your scripting language of choice. If your program requires extra include paths, compiler flags, or whatever, make sure to add the necessary flags to both the test compile and the real compile.
'yourfile.c' would look something like this:
#include <windows.h>
unsigned long long get_tick_count(void) {
#ifdef CONF_HASGETTICKCOUNT64
return GetTickCount64();
#else
return GetTickCount();
#endif
}
You're asking about C but the question is tagged C++ as well ...
In C++ you would use SFINAE technique, see similar questions:
Is it possible to write a template to check for a function's existence?
But use preprocessor directives in Windows when provided.
If your code is going to run on OSes berfore Vista, you can't just compile your calls down to GetTickCount64(), because GetTickCount64() doesn't exist on an XP machine.
You need to determine at runtime which operating system you are running and then call the correct function. In general both calls need to be in the code.
Now this may not be true in your case if you don't really need to be able to call either GetTickCount64() on Vista+ machines and GetTickCount() on XP- machines. You may be able to just call GetTickCount() no matter what OS you're running on. There is no indication in the docs that I have seen that they are removing GetTickCount() from the API.
I would also point out that maybe GetTickCount() isn't the right thing to use at all. The docs say it returns a number of milliseconds, but in reality the precision of the function isn't even close to 1 millisecond. Depending on the machine (and there's no way to know at runtime AFAIK) the precision could be 40 milliseconds or even more. If you need 1 millisecond precision you should be using QueryPerformanceCounter(). In fact, there's really no practical reason to not use QPC in all cases where you'd use GetTickCount() anyway.
G'day,
Isn't NTDDI_VERSION what you need to look for?
Update: You want to check if WINVER is 0x0600. If it is then you're running Vista.
Edit: For the semantic pecker head, I meant running a compiler in a Vista environment. The question only refers to compiling, the question only refers to header files which are only used at compile time. Most people understood that it was intended that you're compiling in a Vista env. The question made no reference to runtime behaviour.
Unless someone is running Vista, and compiling for windows XP maybe?
Sheesh!
HTH
cheers,
The Microsoft compiler will define _WIN64 when compiling for 64 bit machines.
http://msdn.microsoft.com/en-us/library/b0084kay%28VS.80%29.aspx
#if defined(_WIN64)
unsigned long long get_tick_count(void) { return GetTickCount64(); }
#else
unsigned long long get_tick_count(void) { return GetTickCount(); }
#endif
If you have to support pre-Vista, I would stick with only using GetTickCount(). Otherwise you have to implement runtime code to check the Windows version and to call GetTickCount() on pre-Vista versions of Windows and GetTickCount64() on Vista and later. Since they return different sized values (ULONGLONG v DWORD) you'll also need to have separate handling of what they return. Using only GetTickCount() (and checking for overflow) will work for both situations, whereas using GetTickCount64() when it's available increases your code complexity and doubles the amount of code you have to write.
Stick with using only GetTickCount() until you can be sure your app no longer has to run on pre-Vista machines.
Maybe it is a good replacement for GetTickCount()
double __stdcall
thetimer (int value)
{
static double freq = 0;
static LARGE_INTEGER first;
static LARGE_INTEGER second;
if (0 == value)
{
if (freq == 0)
{
QueryPerformanceFrequency (&first);
freq = (double) first.QuadPart;
}
QueryPerformanceCounter (&first);
return 0;
}
if (1 == value)
{
QueryPerformanceCounter (&second);
second.QuadPart = second.QuadPart - first.QuadPart;
return (double) second.QuadPart / freq;
}
return 0;
}

Resources