Hi,

I have to create an application which can be executed in Linux and Windows. My question is :

1: Will i have two executables. Each for an environment?
2: Do i have to write two totally different codes for different enviroments. If yes, is there anyway to MAP the code from one enviroment to another.

Thanks

Will i have two executables. Each for an environment?

Yes. Technically you could write an app for one environment and rely on emulation like Wine for running on the other environment, but if you want native support then there will be two executables.

Do i have to write two totally different codes for different enviroments.

It depends. If you use platform dependent APIs (such as Windows UI elements) or do a lot of system level stuff then there will be pieces of code that must be ported.

If yes, is there anyway to MAP the code from one enviroment to another.

Not so much, though you can use platform independent solutions wherever possible. And when you have no choice, isolate the non-portable code as much as possible by wrapping it in classes and functions that can be more easily swapped out with a different implementation.

Do i have to write two totally different codes for different enviroments.

If you stick to only standard libraries (I mean, the C++ standard libraries) and to standard C++, then all you have to do is recompile it for both environments. That's easier said than done for non-trivial codes, often you use non-standard features or libraries without even knowing that you do (some common ones are M_PI and C-functions from the global namespace (not in std::)), so it will just cause you to have to do some modifications to the code to make it compilable on both platforms at the same time. But, after that, the same code should compile on any platforms.

If you use external libraries (include GUI tools), then it depends on the compatility of those libraries. Most respectable libraries provide pretty good cross-platform support.

If you use native OS functions (such as Win32 API function in Windows, or POSIX functions in Unix/Linux/OSX), then you will have to provide different versions for the different target platform. Usually, this is done by wrapping all the platform-specific code into a somewhat isolated part of the code that can easily be swapped for another (one common trick is to have multiple folders, one for each platform, containing only the platform-specific codes and depending on the platform, you change the include/search directories when compiling the entire code-base).

If yes, is there anyway to MAP the code from one enviroment to another.

Not really, at least, not at a low-level. There is rarely a one-to-one relationship between different OS-specific system functions, and even when it seems like there is, the underlying behavior is often quite different. Also, different platforms have very different mechanisms for checking and reporting errors. The closest thing there is to this kind of mapping is an emulation environment like Wine which acts as a layer that looks like a Windows environment to the application running in it, but operates in a Linux OS environment.

However, when you move up one level detached from the actual system calls, you find that most OSes provide basically the same functionalities to the programmer. And so, it is much more common to find cross-platform libraries at that level (like Boost.Thread or Boost.Date-Time).

@Mike : Thanks. Yes, thats the plan that i use the native OS functions in Windows and also POSIX in Unix atleast for the file operations. Actually I was planning to post another question for this but since it related here so i will go ahead and ask it. Can you please tell me pseoudo code or skeleton for the scenario when i have to use different version for different target platform. Also, can you guide me a bit on POSIX and Win API. I have no experience of that and am confused with that.. Thanks

Here is a piece of code I wrote a little while ago (in response to a question about recursion) which incorporates a typical cross-platform switches in the code. Here it is:

#include <iostream>
#include <iomanip>

#ifdef WIN32

#include <windows.h>

static std::size_t get_stack_size() {
  MEMORY_BASIC_INFORMATION mbi;
  VirtualQuery(&mbi, &mbi, sizeof(mbi));
  VirtualQuery(mbi.AllocationBase, &mbi, sizeof(mbi));
  VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
  VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi));
  return mbi.RegionSize;
}; 

#else

#include <pthread.h>

static std::size_t get_stack_size() {
  std::size_t stacksize;
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_getstacksize (&attr, &stacksize);
  return stacksize;
};

#endif

void print_countdown(int i) {
  int new_i = i - 1;
  std::cout << "\rCountdown to stack-overflow: " << std::setw(7) << new_i; std::cout.flush();
#ifdef WIN32
  Sleep(0);
#else
  usleep(0);
#endif
  print_countdown(new_i);
};


int main() {

  print_countdown(get_stack_size() / (8 * sizeof(std::size_t)));

  return 0;
};

You see how this is typically done when you really need to use OS-specific calls. In the above case, I was trying to extract the size of the stack for the current process, and the only way to do that is to call either a set of Win32 API functions or a set of POSIX-thread functions. Also notice how there is clearly no one-to-one correspondance between Win32 calls and POSIX calls, but you can usually do what you need to do in either.

To make it a bit better, you could also separate the OS specific code into separate source files.

Overall, you should try as much as you can to avoid having to do this. In fact, the above is the only time that I can recall that I actually did this myself, but I have seen plenty of code that does it, and it's never pretty. If there is a cross-platform library that does whatever you need to do, use it. That's the best advice.

What is the specific feature that you need to call OS-specific functions for? Chances are, there is a cross-platform library (or even a standard library) that can solve your problem.

Thanks Mike, Your answers are realy helpful. The feature which i am looking for is 'Reading all the files from a folder'. I dont know if there are any cross-platform or standard libraries for it but even if there are my REQUIREMENT is to do it with WIN File API for Windom and its POSIX equvalent for Linux. Bytheway, since mentioning about the Folder reading. Do you have any good hints/advice related to that. That could be useful Thanks :)

This article has been dead for over six months. Start a new discussion instead.