Writing cross-platform apps in C - c

What things should be kept most in mind when writing cross-platform applications in C? Targeted platforms: 32-bit Intel based PC, Mac, and Linux. I'm especially looking for the type of versatility that Jungle Disk has in their USB desktop edition ( http://www.jungledisk.com/desktop/download.aspx )
What are tips and "gotchas" for this type of development?

I maintained for a number of years an ANSI C networking library that was ported to close to 30 different OS's and compilers. The library didn't have any GUI components, which made it easier. We ended up abstracting out into dedicated source files any routine that was not consistent across platforms, and used #defines where appropriate in those source files. This kept the code that was adjusted per platform isolated away from the main business logic of the library. We also made extensive use of typedefs and our own dedicated types so that we could easily change them per platform if needed. This made the port to 64-bit platforms fairly easy.
If you are looking to have GUI components, I would suggest looking at GUI toolkits such as WxWindows or Qt (which are both C++ libraries).

Try to avoid platform-dependent #ifdefs, as they tend to grow exponentially when you add new platforms. Instead, try to organize your source files as a tree with platform-independent code at the root, and platform-dependent code on the "leaves". There is a nice book on the subject, Multi-Platform Code Management. Sample code in it may look obsolete, but ideas described in the book are still brilliantly vital.

Further to Kyle's answer, I would strongly recommend against trying to use the Posix subsystem in Windows. It's implemented to an absolute bare minimum level such that Microsoft can claim "Posix support" on a feature sheet tick box. Perhaps somebody out there actually uses it, but I've never encountered it in real life.
One can certainly write cross-platform C code, you just have to be aware of the differences between platforms, and test, test, test. Unit tests and a CI (continuous integration) solution will go a long way toward making sure your program works across all your target platforms.
A good approach is to isolate the system-dependent stuff in one or a few modules at most. Provide a system-independent interface from that module. Then build everything else on top of that module, so it doesn't depend on the system you're compiling for.

XVT have a cross platform GUI C API which is mature 15+ years and sits on top of the native windowing toollkits. See WWW.XVT.COM.
They support at least LINUX, Windows, and MAC.

Try to write as much as you can with POSIX. Mac and Linux support POSIX natively and Windows has a system that can run it (as far as I know - I've never actually used it). If your app is graphical, both Mac and Linux support X11 libraries (Linux natively, Mac through X11.app) and there are numerous ways of getting X11 apps to run on Windows.
However, if you're looking for true multi-platform deployment, you should probably switch to a language like Java or Python that's capable of running the same program on multiple systems with little or no change.
Edit: I just downloaded the application and looked at the files. It does appear to have binaries for all 3 platforms in one directory. If your concern is in how to write apps that can be moved from machine to machine without losing settings, you should probably write all your configuration to a file in the same directory as the executable and not touch the Windows registry or create any dot directories in the home folder of the user that's running the program on Linux or Mac. And as far as creating a cross-distribution Linux binary, 32-bit POSIX/X11 would probably be the safest bet. I'm not sure what JungleDisk uses as I'm currently on a Mac.

There do exist quite few portable libraries just examples I've worked within the past
1) glib and gtk+
2) libcurl
3) libapr
Those cover nearly every platform and so they are extremly useful tool.
Posix is fine on Unices but well I doubt it's that great on windows, besides we do not have any stuff for portable GUIs there.

I also second the recommendation to separate code for different platforms into different modules/trees instead of ifdefs.
Also I recommend to check beforehand what are the differences in you platforms and how you could abstract them. E.g. this is some OS related stuff (e.g. the annoying CR,CRLF,LF in text files), or hardware stuff. E.g. the previous mentioned posix compability doesnt stop you from
int c;
fread(&c, sizeof(int), 1, file);
But on different hardware platforms the internal memory layout can be complete different (endianess), forcing you to use conversion functions on some of the target platforms.

You can use NAppGUI for both console and desktop apps. The SDK uses ANSI-C and your code will work on Windows/macOS/Linux.
https://www.nappgui.com
It's free and OpenSource.

Related

Multiplatform c project

I have to design a C project that is supposed to be run on Linux. I am very used to design C projects on Windows using Visual Studio or DevC++. Is it feasible to design the project on Windows and then port the code to Linux. Is it possible to use Eclipse CDT for switching compile configurations from Windows to Linux. What should i do? What do you suggest me to do or search?
This is a broad question since we have no info on what you're trying to achieve.
Some guidelines I can share with the limited information provided: in my experience it is feasible to write code on Windows and then port it to Linux although you should expect some differences in the Microsoft compiler and gcc compilers used in Linux/Unix (usually the more a compiler is conformant to the standard, the more it "warns" or won't accept something fishy in your code).
If you're dealing with a large number of dependencies / headers / source structures your project could greatly benefit from using a tool like CMake to deal with all those issues (a meta-generator that can generate makefiles and/or visual studio solutions depending on your platform from the same set of sources).
Also notice that you should NOT use any platform-dependent API in order to render your code portable. If you really need to, make sure to #ifdef those code sections for the specific platform you're compiling your code on.
Finally, if you plan to use a GUI in your application (or even if you're not planning one you might still benefit from the various libraries included), you might use a portable framework like Qt but keep in mind that this would require isolating the C part of your application from the C++ one (Qt). As another choice of your preference, you might also use GTK+.

Status of Oberon readiness for application programming

I am getting interested in the Oberon language and I would like to know: is the language actually used by common programmers or is it still only used by researchers? Is it production-ready? What I have in mind are non-scientific applications requiring GUI support and possibly Internet connectivity (at least client-side POP3 and SMTP functionality).
Also, which of the Oberon flavors would you recommend for my needs (Oberon2, Active Oberon, etc)? The simpler, the better, as long as it is well maintained and has some community.
If possible, I would like to run my applications in a conventional host environment (Windows or Linux), without the need for a special runtime environment or a special operating system.
Thanks
BlackBox has some of what you want, runs on flavors of Windows.
There are also some environments that compile to Java bytecode and target the JVM.
Look at POW, and Gardens Point Component Pascal.
I happen to be using some command-line only tools that are Oberon Compilers.
OO2C is an Oberon to C compiler (but the output is not for human consumption).
Ofront is an Oberon to Human-Readable C, but I haven't yet set up a linux box to run it on. (otherwise, it is supposed to run inside of BlackBox on Windows).
There is also Oxford Oberon Compiler by Professor Spivey. A VERY enjoyable Compiler that compiles to a Virtual Machine, but the whole object code is a self-contained application (albeit command -line).
It is a VERY small download, meant for an educational environment, keeps everything CLEAN, and works well for prototyping some of the grunt work or procedures/modules of your code. It also is supposed to allow bitmap drawing in XWindows in Black and White only, probably for drawing graphs, etc, but I have not had an opportunity to use that feature yet.
It has a GUI-based debugger, profiling, and some other interesting tools, and still is very small by comparison to most modern compilers like gcc. It is also totally stand alone.
Works on Mac, Win, Linux, and has source.
By comparison, OO2C took me about a day of futzing and compiling to get it going (but it is working).
I don't have a Windows box right now, so I can't run my copy of BlackBox, but it had a full GUI, and lots of Source code available at the Component Pascal Collection website.
http://www.zinnamturm.eu/index.htm
If you are looking for source code you should also check out that site in hopes you don't have to reinvent the wheel.
Really a joy to step into Oberon after having to fight C/C++ all day long to get simple stuff done.
OBNC is a new compiler for the latest version (2016) of the original Oberon language by Niklaus Wirth. It compiles via C and makes it easy to interface to existing C libraries.
https://miasap.se/obnc/
Given that Oberon [language] was developed as a complete [operating-]system, and that ETH's CS department ran ALL its computers (even the secretary's) on it I should think it is application-ready. This according to the following PDF:
http://www.ics.uci.edu/~franz/Site/pubs-pdf/BC03.pdf
is the language actually used by common programmers or is it still only used by researchers?
There was/is little use of the original Oberon language outside academia; there was some industrial adaptation of Oberon dialects like e.g. Component Pascal.
Is it production-ready?
Depends on your requirements. Given todays expectations of software developers the (original) language and available toolchains seem very minimalistic.
non-scientific applications requiring GUI support and possibly Internet connectivity ... in a conventional host environment... which of the Oberon flavors would you recommend for my needs?
GUI support and network programming in a conventional host environment is e.g. supported by https://blackboxframework.org as already mentioned, which uses a language related to Oberon.
You could also have a look at https://github.com/rochus-keller/Oberon which includes a platform independend IDE with semantic navigation and a source-level debugger, plus a platform independent foreign function interface as a language extension which allows you to directly use any C shared library, and thus reuse the plethora of existing proven GUI or network libraries out there without having to program in C. It also offers a modern, lean syntax variant without all the semicolons and capitalized keywords, which should appeal especially to younger developers; but of course also the traditional syntax is supported, even mixed modern/traditional syntax projects.

Coding in C in Linux vs Windows. Any adequate debugging oriented C-centric IDE?

I've run into an issue with writing some code in c. My basic problem is that I am pressed for time and the code I am dealing with has lots of bugs which I have to "erradicate" before tomorrow evening.
The bigger part of the problem is that there is no adequate IDE that can do real time debugging, especially when using threads or spawning processes with fork(). I tried Mono, Eclipse, and finally NetBeans, and have concluded that those are very good but not for coding in C. More over the learning curve to utilize the command line debugger properly is quite steep. (Like I mentioned earlier... I am pressed on time.)
So, since I am a C# developer by profession I was wondering whether I can pull this off in VS2003/VS2005/VS2008/VS2010. If I abstain from using system calls, can I do this?
Of particular interest are FILE* descriptor and fread(), fclose(), fseek() methods. I know they are part of the standard C library, however are they tied to the platform itself? Are the headers the same in Linux vs Windows? What about fork() or shared memory?
Maybe if I use VS2010 to build parts of the component at a time (by mocking inputs and stuff), debug those, and then migrate the working code in the overall Linux project would prove most useful?
Any input would be greatly appreciated.
The bigger part of the problem is that there is no adequate IDE that can do real time debugging, especially when using threads or spawning processes with fork().
The Eclipse CDT would probably have the best overall support for C/C++ development and integrated debugging.
Note that multithreaded and multiprocess debugging can be difficult at the best of times. Investing in a good logging framework would be advisable at this point, and probably more useful than relying on a debugger. There are many to choose from - have a look at Log4C++ and so on. Even printf in a pinch can be invaluable.
So, since I am a C# developer by profession I was wondering whether I can pull this off in VS2003/VS2005/VS2008/VS2010. If I abstain from using system calls, can I do this?
If you take care to only use portable calls and not Win32-specific APIs, you should be ok. Also, there are many libraries (for C++ libraries such as Boost++ that provide a rich set of functionality which work the same on Windows, Linux and others.
Of particular interest are FILE* descriptor and fread(), fclose(), fseek() methods. I know they are part of the standard C library, however are they tied to the platform itself? Are the headers the same in Linux vs Windows? What about fork() or shared memory?
Yes, the file I/O functions you mention are in <stdio.h> and part of the portable standard C library. They work essentially the same on both Windows and Linux, and are not tied to a particular platform.
However, fork() and the shared memory functions shmget() are POSIX functions, available on *nix platforms but not natively on Windows. The Cygwin project provides implementations of these functions in a library for ease of porting.
If you are using C++, Boost++ will give you portable versions of all these system-level calls.
Maybe if I use VS2010 to build parts of the component at a time (by mocking inputs and stuff), debug those, and then migrate the working code in the overall Linux project would prove most useful?
You could certainly do that. Just be mindful that Visual Studio has a tendency to lead you down the Win32 path, and you must be vigilant to not start using non-portable functions. Fortunately the library reference on MSDN gives you the compatibility information. In general, using standard C or POSIX calls will be portable. In my experience, it is actually easier to write on *nix and port to Windows, but YMMV.
Looks like I am the first to recommend Emacs here. Here is how Emacs works. When you install it, it is simply a text editor with a lot of extensions(debugger and C font-locking are included by default). As you start using it and install the extensions you miss, it becomes more than just an editor. It grows to become an IDE very soon and easily, then on to something that can eschew the OS under one frame.
Emacs might take long to learn, in the mean time, you could use Visual Slick Edit if you are not pressed on the cost part. I have used it on both platforms and seen it work good with version control, tags, etc.
Perhaps Code::Blocks? I love it and while it says it's for C++ it is, of course, very good for plain C as well.

Porting a large C project from Unix to Windows

So, I have a large C project that was built entirely on Unix (SPARC Solaris). me and several others have begun to revisit it because their was some interest in a windows build.
none of us have done this with a project of such size, so for starters, has anyone ported something from unix to windows and could maybe give me some pointers or how they did it.
our first step on our plan was to decide on a compiler/dev environment.
it seems that our options are MS Visual Studio, Cygwin, mingw/gcc, and Windows Services for UNIX (SFU).
we are on a fairly short timetable so we want to rewrite as little code as possible.
so, Deciding on a compiler.
Another issue is that the code does use POSIX thread commands (pthread, etc)
we would prefer to compile natively, not using some sort of layer between the executable and the OS. unfortunatly with the pthread calls in our code, this may not be possible.
I believe both Cygwin and SFU do just that. Cygwin has a .dll that must be included in compiled code to work. I am not sure about SFU, any information about that would be greatly appreciated. It seems like it would be a good option but was developed to allow for UNIX compiled software to run on a windows machine with SFU, not any old windows box.
mingw does have the ability to create native exes, but lacks the POSIX support.
So, can anyone give me any more information, suggestions, knowledge on any of these compilers in this context. or any experience they have with this sort of thing, it is greatly appreciated.
Short timetable? CygWin, plain and simple.
Despite your preference to not use a layer, that's going to provide the fastest path and you don't seem to indicate that the timeframe requirement is flexible.
We've ported both command-line and X-based UNIX programs to Windows using CygWin with minimal hassle.
Cygwin is likely the fastest path to a working executable. However it will leave you with some interesting distribution choices. Most obviously, cygwin.dll becomes a dependency. Its licensed GPL, unless you pay money to buy commercial use rights.
Cygwin is not particularly friendly to an ordinary Windows user. Its goal is to provide a full POSIX experience on Windows, supplying a shell, all the familiar *nix utilities, and even a port of X. However, it also remaps the Windows disk drive naming into a POSIX-like file system. I've never attempted to distribute an application built for Cygwin to machines that don't already have a full Cygwin installation. I will note that to my knowledge none of the big well-known open-source applications with Windows ports are based on Cygwin.
If the only hard POSIX dependency you have is pthreads, then that is solvable. There is a pthreads port built on native Windows threads that works well with MinGW. IIRC, it is even distributed along with MinGW, or at least is one of their core supported packages.
If the rest of your handling of file names is largely as opaque strings, you may not even need to care about changing / to \. The Windows API is generally happy to treat either character as a path separator, even mixed in the same name. It is the CMD.EXE and early DOS convention of using / for command line options that prevents the use of / for pathnames at the command prompt, not the underlying Windows API.
For tools that might make porting your build process easier, check out the MSYS component of MinGW. It provides a lightweigh fork from the Cygwin environment in which enough *nix utilities are available to generally run ./configure and similar processes.
In addition, the GnuWin32 project has ports of a large number of utilities and libraries that are all built to run as native Windows applications without unusual dependencies.
If the code is (at least mostly) portable and the only major issue is the use of pthreads, you might want to use the Pthreads Win32 library. While incomplete, it's sufficiently complete and accurate to deal with most pthreads code I've tried it with. While normally built as a DLL, this can also be built as a static library to avoid creating an extra dependencies in your executable.
That, of course, leaves everything else to port -- but you haven't said enough to even guess whether porting the rest within your timeframe is at all reasonable.

What is the relationship between C and the Windows API?

I looked at some other questions on SO and its not clear if c is built on top of, under, or alongside the WINAPI. Like for example could someone write something in pure c that was able to open a window, or would they need to use the windows api?
I noticed similarities between the c (library?) version of opening a file (fopen) vs the windows API version (CreateFile) which makes me wonder if one is just a wrapper for the other. Does anyone know?
If windows is running; is a programmer forced to program using the windows api to get something running on it or can the programmer not use the windows api at all and directly access the hardware (ie. does the windows operating system protect access to the hardware)?
Which is more portable between different versions of windows of windows ce. The documentation I found (which has now changed) used to say that CreateFile only goes back to version 2.0 of windows ce (here: http://msdn.microsoft.com/en-us/library/ms959950.aspx -
Notice the note on the link at the very bottom that shows the supported version information has been changed). So what is one supposed to use for windows ce version 1? In other words is programming using c functions or the functions labeled WINAPI more likely to work on all versions of windows CE?
I read the following in a book about programming windows ce and it confused me, so all of the above questions can be understood better in context of making sense of the following:
Windows CE supports the most of the same file I/O functions found on Windows NT and Windows 98. The same Win32 API calls, such as CreateFile, ReadFile, WriteFile and CloseFile, are all supported. A Windows CE programmer must be aware of a few differences, however. First of all, the standard C file I/O functions, such as fopen, fread, and fprintf, aren't supported under Windows CE. Likewise, the old Win16 standards, _lread, _lwrite, and _llseek, aren't supported. This isn't really a huge problem because all of these functions can easily be implemented by wrapping the Windows CE file functions with a small amount of code.
My understanding of wrapping is that you have to have something to wrap, given how it appears that win16 and c library are not available is he stating to wrap the CreateFile function to make your own c-like version of fopen? (The only other thing I am aware of is assembly, and if that is what he was suggesting to wrap it wouldn't be written in such a casual manner.)
Given the above, what is the dependency relationship between c language (syntax, data structures, flow control), the c function library (ex. fopen), and the windows api (ex. CreateFile)?
C existed long before Windows did. The Windows API is a bunch of libraries written in C. It may or may not be possible to duplicate its functionality yourself, depending on what Microsoft has documented or made available through the API. At some level it is likely that fopen() and CreateFile() each call the same or a similar operating system service, but it's unlikely that one is a strict wrapper for the other. It would probably be difficult to bypass the Windows API to access the hardware directly, but anything is possible given enough time and programming effort.
C doesn't know anything about GUIs, and VERY little about operating systems at all. Anything you do graphics-wise in C is through the use of libraries, of which the win32 api is an example.
The windows API is implemented in the C programming language. Functionality provided by the C standard libraries, such as fopen, is portable because it is compiled down to the appropriate assembly code for different architectures by different compilers. Windows API functions such as CreateFile only work on machines running Windows and are therefore not portable.
In theory it's possible to write C that talks directly to the hardware. Back in the days of MS-DOS (for one example) quite a few of us did on a fairly regular basis (since MS-DOS simply didn't provide what we needed). Edit: On some small embedded systems, it's still quite commonplace, but on typical desktop systems and such this has mostly disappeared.
Two things have changed. First, modern systems such as Linux and Windows are much more complete, so there's a lot less need to deal directly with the hardware. Second, most systems now run in protected mode, so normal user code can't talk directly to the hardware -- it has to go through some sort of device driver.
Yes, most of the C library uses the underlying OS so (for example) on Windows, fopen and fwrite will eventually call CreateFile and WriteFile, but on Linux they'll eventually call open and write instead.
I noticed similarities between the c (library?) version of opening a file (fopen) vs the windows API version (CreateFile)
Not surprising. They do similar things.
[is] one is just a wrapper for the other? Does anyone know?
You can't find out because the source code is owned and kept as a trade secret.
It doesn't matter which is more "fundamental". You use the windows API from a windows program. You use C API's from C programs.
Notice that it doesn't matter. You can use C API's or Windows API's intermixed.
If windows is running; is someone forced to use the windows api to get something running on it or can they bypass windows entirely and directly access the hardware?
"Directly access the hardware"? What does that mean? If windows is running, then.... well... Windows is running. Windows mediates your access to the hardware.
Use bootcamp or GRUB or some other bootloader to bypass Windows and have "direct access to the hardware".
If they can, is it possible to damage the hardware if you don't know what your doing?
What does this mean? Are you asking if you can "damage" some rotating media (i.e., disks) by misusing their drivers? You can corrupt your hard disk no matter what OS you're running or not running. A privileged account and dumb software can write bad data on a disk. Does that count as "damage"?
Which is more portable?
What does that mean? To another Windows computer? To a computer not running Windows? What are you asking about? Please clarify your question to define what you mean by "portable".
between different versions of windows
Since different Windows are mutually incompatible, I generally suggest using only the POSIX standard libraries and avoiding all Windows API's.
However, some Windows variants (e.g. Windows mobile for phone vs. Windows "Server") are essentially totally incompatible. There is very little reason for any piece of software to run on both OS's. Portability doesn't much matter. Why try to run a phone app on a server?
Edit
So theres the c language on the bottom (closest to the hardware), then the windows API next, then the C library on top of the Windows API?
This doesn't make sense. You're mixing up two unrelated things. The "language" and the "libraries" have little to do with each other.
Also, the API is not the operating system. So by using Windows "API" all the time, you're making this more confusing than it needs to be.
Here's a way to look at this.
The Windows Operating System has several API's. There are underlying function libraries that are not part of the application interface. They're "internal".
It has a native Windows API. Callable from C.
It has a POSIX API. Callable from C. In some cases, the Posix API generally uses the Windows API.
Most operating systems, including Windows are written in C (and or assembler). The Library is then modified for each operating system to do the basic stuff. (Sockets, Files, Memory, etc ...).
The WINAPI is just a bunch of libraries (written in C and/or Assembler) that allow access to functionality within the OS.
It is not Windows related, after you changed your question, I think what you are trying to understand is the bootstrapping of an OS (Windows or other).
The book Operating Systems Design and implementation discusses the implementation of Minix (Which Linux is based on).
the WINAPI provides an interface that developers in C can use in order to use the WINAPI functionality. C++ programs can also use it.
Operating systems such as Windows contain WINAPI libraries that provide access to some operating system functionality and sometimes contact with Hardware, these libraries are written in C
Carl Norum pointed out that C existed long before Windows, but don't forget that the Windows API kind of started with the MS-DOS API, which kind of started with the CP/M API. C only existed a short time before CP/M.
Lots of answers seem to imply that the Windows API is built on C, but that seems doubtful too. __stdcall is a synonym for PASCAL, which was a keyword in Microsoft's C compilers because the Windows API was built on Pascal. __cdecl is the default for function calls in C and C++ programs compiled by Visual Studio but it doesn't work on calls to APIs.
The relationship between C and the Windows API is that they are capable of working with each other.
As a fun note, you can really get a handle on the 'power' of the Windows API by taking a look at AutoIt http://www.autoitscript.com/autoit3/. AutoIt is a great little scripting language that can create GUIs, run command line apps, manipulate windows and processes, etc. Yes, it does File I/O and networking.

Resources