What is the relationship between C and the Windows API? - c

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.

Related

What makes a program Linux or Windows? [duplicate]

This question already has answers here:
Why an executable program for a specific CPU does not work on Linux and Windows?
(6 answers)
Closed 8 years ago.
So I've been learning C the past few weeks and I finished this simple breakout game on a Fedora based virtual machine.
I wanted to show it to my friends that's on Windows. From what I told, you can't simply run a Linux program on a Windows which makes sense.
My questions is, what makes a program a Linux or Windows program? Is it the way you coded the program? The editor? The OS? The compiler you used?
Can you make a program specifically for Windows if you are on Linux? How?
Roughly, different operating systems read executables in different binary formats and these don't happen to be compatible. So, when you are building the game from source code, you're building for a given platform, using the formats of that platform. You are correct in guessing that the platform you're building for (also called the target platform) doesn't have to be the platform you're building on (this process is called cross-compiling).
Additionally, it's often the case that some source code isn't translatable to all platforms. For example, code that calls to a library file that's only available on Windows can't be compiled (or cross-compiled) for non-Windows systems. The way that every operating system creates user interfaces (such as windows, touch screen pages, etc) is different not only at the binary level, but often also at the source-code level.
The problem of the second paragraph can be partially mitigated by cross-platform libraries (like GTK, OpenGL, OpenCL, etc) that offer the same mechanisms regardless of the operating system you're targeting. They often achieve this by using conditional compilation and other "tricks" behind the scenes.
The problem of the first paragraph is more difficult, but workarounds have appeared as well, utilizing some other binary formats (Java archives, CLR assemblies, etc). These formats aren't special in any way. The trick is that they aren't meant to be directly read by any operating system - instead, they are fed to another mechanism (the JVM, the CLI, etc) which has already been built by someone multiple times for multiple platforms (including Windows and Linux) and that mechanism manages the execution of those programs, often from a common binary file without the need for you to target any one specific platform. They usually achieve this by automatically compiling the code for you just before it runs (a process known as Just-in-Time compilation).

Can the Windows API be utilized using just C?

I'm in the process of teaching myself C (coming from Java). I appreciate the language a lot, and one of the main reasons I am learning it is so that I can utilize the JNI feature built into Java to write native code when necessary. My question is mainly about the Windows API. Can I use the functions and features of the API using just C?
Will the Windows API be compatible with pure C code or does it contain classes and such that can only be utilized by C++ code?
Also, if I compiled a shared library on a Windows machine as (lib.sl NOT lib.dll), would it work on another machine (Mac/Linux)?
The Windows API (aka Win32 API) is a pure C library.
No you cannot use a Windows shared library on another non-Windows machine unless there is a software that supports Windows ABI - such as Wine or ReactOS.
Win32 API like others have pointed out is pure C. It means, once you get a hold of it, you will know everything about how the Operating system works. It is the same case usually with other operating systems as well. If you are after MFC/COM+ or Java wrappers, it is quite the opposite even if you can build great programs.

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.

Writing cross-platform apps in 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.

Resources