Getting Free RAM in Windows Programmatically? - c

All,
Need some help here. I am from a purely Java background and don't know much about C programming. Basically I need to write a C program (and create an executable) which would output the number of Free Bytes (RAM) on a Windows machine (XP/2008/7)
I have doing some research about it and found that there is a function called GlobalMemoryStatusEx and also a link on this:
http://msdn.microsoft.com/en-us/library/aa366589(v=vs.85).aspx
I have installed cygwin with gcc and the above program doesn't even compile for me. I know I am doing something stupid here..
$ gcc hello.c -o hello.exe
hello.c:3:19: error: tchar.h: No such file or directory
hello.c: In function `main':
hello.c:7: error: `MEMORYSTATUSEX' undeclared (first use in this function)
hello.c:7: error: (Each undeclared identifier is reported only once
hello.c:7: error: for each function it appears in.)
hello.c:7: error: expected `;' before `statex'
hello.c:9: error: `statex' undeclared (first use in this function)
Any help is very much appreciated!

As larsmans said, cygwin is not a Windows native compiler. In addition to MinGW, you might also consider Visual C++ 2010 Express.

Cygwin by default emulates a Unix API on Windows, rather than presenting the Windows API.
You may have more success with the MinGW package, which is GCC for Windows + Windows API.

If you are unfamiliar with C, and all you want to do is write this little program for Windows, you might find it easier to get started with the free Visual C++ Express. Chances are that MSDN examples will work out of the box.
Edit: You mention Java, but it is not totally clear whether the sole purpose of this C app is to be invoked from Java. In case it is, I thought I'd mention something called JNative. It appears to be a pure Java library that contains, among other things, a wrapper for GlobalMemoryStatusEx. Note that I found JNative via a Google search and haven't used it myself.

The function to which you refer is a Windows API function, which means you cannot call that function from cygwin, which is a POSIX emulation layer on top of Windows.
You have a few options at this point:
You could download download and install the Windows SDK, which includes the Visual Studio C/C++ compiler(s), for free.
You could download a copy of Visual C++ Express Edition for free.
If you are a student, you could get a full copy of Visual Studio 2010 from MSDNAA (provided by your University) or from DreamSpark.
You could purchase a full copy of Visual Studio.
You could download and install MinGW, which is the GCC compilers ported to Windows.
Note that all of the Microsoft compilers support the entire Win32 API. MinGW is limited in its handling of Unicode on Windows, it does not support COM (so if you want to call COM APIs it's a pain), and it doesn't include all of the headers included with the Windows SDK.
GCC is a great compiler, its just not all that great in terms of its Windows support.

The answers presented are correct, but I don't feel that they explain the problem properly.
Unix and Unix-like operating systems strive to conform to a standard API called POSIX. Windpws does not conform to POSIX. Cygwin was written as way to provide POSIX compliance on Windows. Thus, when you compile on Cygwin, you are compiling on a POSIX API, not a Windows API. The function you found on MSDN does not exist in POSIX. Threefore, you get compile errors.
MinGW is gcc ported to Windows. It is aware of Windows API's with the proper includes. Visual Studio's nmake is the same in this regard (provides access to the Win API).

To use cygwin gcc to compile programs using the Win32 API, you'll want the mingw-i686-headers package (which includes header files like tchar.h).
Then, you may also need to define some macros to enable newer APIs.

Related

Cross-compiling from Linux to Windows with Clang

I am trying to cross-compile C applications from Linux (64 bit) to Windows (64 bit) using Clang. I read the page on cross-compilation, which wasn't too helpful.
As a simple test, I have the following code in test.c:
#include <stdio.h>
int main()
{
puts("hello world");
return 0;
}
My best guess so far is clang -o test -target x86_64-win64-?ABI? test.c. However, I have no idea what ABI Windows 64 bit uses. When I run clang with the target triple x86_64-win64-abcdefg, it seems to compile fine--that is, it finishes without error and results in something that is a somewhat-valid binary. That doesn't make any sense, considering abcdefg is definitely not a valid ABI. The resulting binary is far too big for such a small program, and Windows seems to think it's a 16-bit program (???). Disassembling it reveals references to "linux" and "gnu", so it would seem Clang is not even trying to compile for Windows.
Targeting win32 (x86_64-win32-???ABI???) results in the following error message:
test.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^
1 error generated.
This error, if I'm not mistaken, is the result of it not knowing where to look for system files. I assume Clang does store Windows header files somewhere, since it claims to be able to cross-compile; but where? If it doesn't, is there somewhere I can download them?
Is there a list of all the architectures, systems, and ABI's Clang supports somewhere? The list on the cross-compilation page is not comprehensive.
The page also suggests using -mcpu=..., but a warning suggests that is outdated. Instead, as the warning recommends, I tried -mtune=x86_64. This seems to have no effect. Is this even necessary, considering the architecture is specified in the target triple?
I have seen some literature that suggests I need lld, LLVM's experimental linker. Is this the case? I have had some issues compiling lld, and would like to avoid it if possible.
Your best option to develop Window binaries using clang is Mingw-w64, as you need more than just a compiler to compile for another system. You also need a linker for that system as well as libraries to link against, so basically you need an SDK for the platform you are targeting and Mingw-w64 comes with everything you require.
https://www.mingw-w64.org/downloads/
You can install it on a Linux system or macOS system and cross compile or you can install it directly on a Windows system and compile natively, without the requirement to have anything like the SDK of Visual Studio (VS). Actually the same code should compile with any installation of Mingw-w64 regardless of the system you are using for building it.
Please note that Mingw does not give you a POSIX API on Windows. You will have the standard C/C++ API available that every platform must support and for everything else, you have to use native Windows API just like you'd have to when developing software with VS. As not everyone may understand what I've just said, here's an example:
You can use fopen() to open a file as that is a standard C API function that every platform supports. But you cannot use open() to open a file, as that is a POSIX function defined in unistd.h and this header doesn't natively exist on Windows (not unless you have installed a POSIX subsystem which is not even available for all Windows version).
In Windows you have windows.h and instead of fopen() you can use the function CreateFile(), which despite its name does not always create a file, it can also open existing ones for reading, and then you will get a HANDLE that you need to pass to CloseHandle() once you are done with it (which is like close() on UNIX systems).
If you would like to get a POSIX-like API on Windows with no requirement of users having to install one, so you can share the same code between your Windows and Linux projects, appropriate wrappers do exist for that but that is not related to the compiler or SDK you are using. These are just Windows libraries you are liking against and that implement some fraction of the POSIX API on top of the Windows API; which sometimes comes with caveats. It's the opposite of Wine which implements most of the Windows API on top of POSIX and other native system APIs.
So you see, what makes porting C/C++ code hard is not the language itself but the libraries that act as a layer between your code and the system below it, as they differ from system to system, even between POSIX or POSIX-like systems. There are fundamental differences between Linux, FreeBSD, and macOS, despite the fact that they share a lot of the same API, too. And if you want to test your Windows binaries after the build, you either need a real Windows environment to do so or at least an emulated one like Wine does provide.
The question is a bit old, but I hope this answer will help someone else.
Hypothetically, what you need is a cross-compiler that runs on Linux but builds a Windows executable using Visual Studio provided headers and libraries. The link you provided redirects you to this page which tells you how to generate one. Hypothetically, you can build LLVM version 7 like this:
cmake -G Ninja -H. -B../_bin \
-DLLVM_ENABLE_PROJECTS="llvm;clang;lld" \
-DCMAKE_INSTALL_PREFIX=/opt/llvm-win32 \
-DLLVM_TARGETS_TO_BUILD=X86 \
-DCMAKE_BUILD_TYPE=Release \
-DCLANG_TABLEGEN=/mnt/data/projects/llvm-org/dl/clang-tblgen-7 \
-DLLVM_TABLEGEN=/mnt/data/projects/llvm-org/dl/llvm-tblgen-7 \
-DLLVM_DEFAULT_TARGET_TRIPLE=i686-windows-msvc \
-DLLVM_TARGET_ARCH=i686 \
-DLLVM_TARGETS_TO_BUILD=X86 \
You may have to tweak clang/lib/Driver/ToolChains/MSVC.cpp source file so the shell separator is changed from ; to : because on Unix shells, colon is used for separating multiple paths in variable.
One more thing. LLD defaults to Windows 7 in COFF format. You may either statically or creatively modify Configuration::MajorOSVersion and Configuration::MinorOSVersion in lld/COFF/Config.h if you like to compile for an older Windows. Check Windows Versions for the correct version you like to support. Perhaps, an environment variable OS_VER could carry this information.
But even then, that's just the first step. You still would need Visual Studio installed somewhere. This is where LLVM/clang will look for even basic headers like stdio.h or libcmt.lib. Hypothetically, if you have a Visual Studio 6 or later installed somewhere you could use that. Just make sure to rename all the files and directories to small-case (again, because Linux).
After that, triggering the compiler is simple. Something like:
export VCINSTALLDIR=/mnt/data/projects/VC98
__inc="${VCINSTALLDIR}/include"
__inc="${__inc}:${VCINSTALLDIR}/atl/include"
__inc="${__inc}:${VCINSTALLDIR}/mfc/include"
export INCLUDE=${__inc}
__lib="${VCINSTALLDIR}/lib"
__lib="${__lib}:${VCINSTALLDIR}/mfc/lib"
export LIB="${__lib}"
export OS_VER="4.10" # Windows 98
exec /opt/win32/bin/clang \
-fms-compatibility \
-fms-extensions \
-fmsc-version=1200 \
-fuse-ld=lld \
$*
in a shell script will do. The INCLUDE and LIB variables are honored by LLVM. Save it as something like i686-windows-msvc6-cc and you are good to go. Hypothetically, you can now invoke the compiler on your test source like:
i686-windows-msvc6-cc -o test.exe test.c
Then, boot back into Windows or load your VM and execute test.exe.
Note this is all hypothetical because MSVC terms and conditions don't allow you to fool around with their SDK like this. This could likely also be the reason why no one distributes a cross-compiler like this either. You can of course, try this hypothetically for educational purposes. Your best options is to use the one generated with MinGW instead like Mecki suggested.
I've installed mobaxterm on my windows 10 machine. There is a free version. It provides an xserver. It contains an installation of cygwin and you can start a local terminal. you just type: apt-get install clang and clang is ready to compile and finds stdio.h without complaining.
But if you intend to run the resulting executable not on mobaxterm/cygwin but inside windows itself, you need to compile with mingwin instead.

conio.h is missing from Windows

I usually use VS but trying cygwin for the first time. I am using windows 7 but on compiling hello world program using gcc, it says "fatal error: conio.h: no such file or directory".
I am using Windows 7 and it seems conio.h is missing from my system. Can someone please tell me how to resolve this issue.
Thanks!!
In Cygwin there doesn't exist any such header file called conio.h! Also, you don't need it either because it automatically holds screen for you without using getch() and for clrscr() you do have system("clear") in Cygwin!
conio not being part of the standard library, you cannot expect it to be available cross-platform, or even between compilers on the same platform.
Being, non-standard, the name conio has been used by both Borland and Microsoft for libraries with differing APIs - Microsoft's is much smaller. So for that reason you might avoid it for portability.
It is not a matter of conio not being on Windows, Cygwin is a POSIX API layer and tool-chain for building and running POSIX code on Windows. The libraries provided with it are independent of those provided with Visual Studio.
There are a number of solutions including:
Use an alternative console I/O library, such as ncurses.
Use a conio source code implementation for Linux such as this (which uses ncurses and implements Borland's API).
The second solution is perhaps useful if you have a lot of legacy code using conio, but is overkill if you just want to prevent a console windows from closing. For that you could just use getchar() in any case and accept that you will have to press enter rather than any key.
If you are using Cygwin just to be able to use GCC on Windows, you might be better off using MinGW/GCC instead. This uses Microsoft's C runtime rather than GNU, and the Win32 API rather than POSIX.

A simple explanation of what is MinGW

I'm an avid Python user and it seems that I require MinGW to be installed on my Windows machine to compile some libraries. I'm a little confused about MinGW and GCC. Here's my question (from a real dummy point of view):
So Python is language which both interpreted and compiled. There are Linux and Windows implementations of Python which one simply installs and used the binary to a execute his code. They come bundled with a bunch of built-in libraries that you can use. It's the same with Ruby from what I've read.
Now, I've done a tiny bit a of C and I know that one has a to compile it. It has its built-in libraries which seem to be called header files which you can use. Now, back in the school day's, C, was writing code in a vi-like IDE called Turbo-C and then hitting F9 to compile it. That's pretty much where my C education ends.
What is MinGW and what is GCC? I've been mainly working on Windows systems and have even recently begun using Cygwin. Aren't they the same?
A simple explanation hitting these areas would be helpful.
(My apologies if this post sounds silly/stupid. I thought I'd ask here. Ignoring these core bits never made anyone a better programmer.)
Thanks everyone.
MinGW is a complete GCC toolchain (including half a dozen frontends, such as C, C++, Ada, Go, and whatnot) for the Windows platform which compiles for and links to the Windows OS component C Runtime Library in msvcrt.dll. Rather it tries to be minimal (hence the name).
This means, unlike Cygwin, MinGW does not attempt to offer a complete POSIX layer on top of Windows, but on the other hand it does not require you to link with a special compatibility library.
It therefore also does not have any GPL-license implications for the programs you write (notable exception: profiling libraries, but you will not normally distribute those so that does not matter).
The newer MinGW-w64 comes with a roughly 99% complete Windows API binding (excluding ATL and such) including x64 support and experimental ARM implementations. You may occasionally find some exotic constant undefined, but for what 99% of the people use 99% of the time, it just works perfectly well.
You can also use the bigger part of what's in POSIX, as long as it is implemented in some form under Windows. The one major POSIX thing that does not work with MinGW is fork, simply because there is no such thing under Windows (Cygwin goes through a lot of pain to implement it).
There are a few other minor things, but all in all, most things kind of work anyway.
So, in a very very simplified sentence: MinGW(-w64) is a "no-frills compiler thingie" that lets you write native binary executables for Windows, not only in C and C++, but also other languages.
To compile C program you need a C implementation for your specific computer.
C implementations consist, basically, of a compiler (its preprocesser and headers) and a library (the ready-made executable code).
On a computer with Windows installed, the library that contains most ready-made executable code is not compatible with gcc compiler ... so to use this compiler in Windows you need a different library: that's where MinGW enters. MinGW provides, among other things, the library(ies) needed for making a C implementation together with gcc.
The Windows library and MSVC together make a different implementation.
MinGW is a suite of development tools that contains GCC (among others), and GCC is a C compiler within that suite.
MinGW is an implementation of most of the GNU building utilities, like gcc and make on windows, while gcc is only the compiler. Cygwin is a lot bigger and sophisticated package, wich installs a lot more than MinGW.
The only reason for existence of MinGW is to provide linux-like environment for developers not capable of using native windows tools. It is inferior in almost every respect to Microsoft tooolchains on Win32/Win64 platforms, BUT it provides environment where linux developer does not have to learn anything new AND he/she can compile linux code almost without modifications. It is a questionable approach , but many people find that convenience more important than other aspects of the development .
It has nothing to do with C or C++ as was indicated in earlier answers, it has everything to do with the environment developer wants. Argument about GNU toolchains on windows and its nessessety, is just that - an argument
GCC - unix/linux compiler,
MinGW - approximation of GCC on Windows environment,
Microsoft compiler and Intel compiler - more of the same as names suggest(both produce much , much better programs on Windows then MinGW, btw)

Run C program written in Linux on Windows

I have C program which I wrote in Linux that runs very well. Now I want to run it on Windows.
How do I easily run it on Windows?
Elaborating a bit on the answers from caf and jartieda...
Cygwin is an attempt to emulate a (nearly) complete POSIX execution environment in a native Windows process. It is complete enough that a surprising amount of Unix application code simply compiles and runs using the familiar ./configure && make && make install idiom. This trick was done by supplying a DLL that emulates POSIX system calls using the Windows API. Based on that, you get a complete GCC toolchain, bash, and all the usual command line utilities you are used to. One downside is that the compiled program is dependent on the Cygwin DLL, which makes it tricky to deliver the result to a system that does not already have Cygwin installed and whose user doesn't want to use a Unix shell.
MinGW is a port of the GCC toolchain that generates native Windows applications that depend on the well known (and distributed with Windows itself) MSVCRT.DLL C runtime library. It makes no attempt to emulate a POSIX operating system, but applications that are mostly based on the standard C libraries, will often build essentially unchanged.
MSYS is a compile-time environment that provides enough Unix utilities (including bash) to often allow ./configure to run, and if the project supports the results, finish the build with MinGW's GCC. The result is a native Windows executable that does not depend on any DLLs you don't deliberately use aside from MSVCRT.DLL. Although the MSYS environment itself was a fork of an early version of the Cygwin project, it is primarily intended to be used to provide a unix-like place to compile native Windows applications: one would generally not build new applications based on its runtime environment.
Another approach to compiling for Windows is to use the MinGW cross compiler on linux. A number of MinGW's core developers work that way, testing they product either under Wine, or under Windows running in a VM or a separate PC.
If the program has a GUI component, then you may have additional difficulties. Some GUI frameworks are available for both Linux and Windows. Qt, wxWidgets, and IUP all leap to mind, but there are others out there.
Edit: I've improved the paragraph above about MSYS to emphasize that it is intended to be a compile-time environment for building programs that run as native Windows applications, and not a full POSIX environment like Cygwin.
Note, also, that there is always the option of porting the project to one of the more traditional compilers for Windows development. Open Watcom, the Borland compilers, and Microsoft all have free or inexpensive versions, although often enough not under licenses that make the opens source community entirely happy.
This approach probably requires more effort because the differences between a Linux environment and the Windows environment become more visible when you also switch from one toolchain to another. This is especially true of the Microsoft compilers which are historically not as fully standards compliant as GCC.
The easiest way is to install the Cygwin environment, and compile it under that.
best way recompile it all using mingw compiler.
easy way recompile it under cygwin environment.
The answers you got so far, focus on installing the GNU operating system on the Windows kernel; but you could also use freeware tools from Microsoft. This solution is probably most attractive if you want to continue to develop on Linux, and only do a little work for porting on Windows:
Microsoft offers a simplified version of their development environment as freeware: Visual Studio Express (download). If your program does only file IO it will probably compile unmodified, because Microsoft supplies the C standard library too.
For GUI I also wholeheartedly recommend the Qt framework. It is very well written and documented; it is now licensed under the LGPL, so you can link it to proprietary applications without any cost. However it is written in C++ so you would need to change the programing language. For integration of QT with Visual Studio Express: I believe it works, but you need to try it out. About five years ago I tested the integration of (proprietary) QT and (professional) Visual Studio for my employer, and it worked perfectly.

C: Running Unix configure file in Windows

I would like to port a few applications that I use on Linux to Windows. In particular I have been working on wdiff. A program that compares the differences word by word of two files.
Currently I have been able to successfully compile the program on windows through Cygwin. However, I would like to run the program natively on Windows similar to the Project: UnixUtils.
How would I go about porting unix utilities on a windows environment?
My possible guess it to manually create the ./configure file so that I can create a proper makefile. Am I on the right track? Has anyone had experience porting GNU software to windows?
Update:
I've compiled it on Code::Blocks and I get two errors:
wdiff.c|226|error: `SIGPIPE'
undeclared (first use in this
function)
readpipe.c:71: undefined reference to `_pipe'
readpipe.c:74: undefined reference to `_fork
This is a linux signal that is not supported by windows... equvilancy?
wdiff.c|1198|error: `PRODUCT'
undeclared (first use in this
function)|
this is in the configure.in file... hardcode would probably be the fastest solution...
Outcome:
MSYS took care of the configure problems, however MinGW couldnt solve the posix issues. I attempt to utilize pthreads as recommended by mrjoltcola. However, after several hours I couldnt get it to compile nor link using the provided libraries. I think if this had worked it would have been the solution I was after.
Special mention to Michael Madsen for MSYS.
Yes. If you stick to the standard C library, and POSIX functions, most is available on Windows. You may just have to find the implementations. There are implementations of things that do not require Cywgin or MinGW (such as a pthreads package, etc.)
Also, there is a great book that is written in the style of W. Richard Steven's Advanced Proramming in the UNIX Environment, and the book is Windows System Programming, author Johnson Hart. He has a 4th edition. It focuses on System Programming, there is no GUI treatment whatsoever.
http://www.amazon.com/Windows-Programming-Addison-Wesley-Microsoft-Technology/dp/0321657748
It is the best book I know of for a UNIX programming moving to Windows.
You can have a look at MinGW (and MSYS), which are similar to cygwin, but gcc produce native Windows executables. However, since the Unix emulation is not as good as cygwin, you may have to adjust your code.
Always try to following standarts even when porting applications. POSIX compliant compilers exist on windows/Linux. You can try mingw. It has full toolchain required to build standart POSIX application (GNU Linux as well). Check out Dev-Cpp it eases the work.
MinGW is about the easiest way to get gcc and associated binary utilities (including gdb) on a Windows PC. It includes header files and import libraries so that you can call native Windows APIs. If you want more of an integrated IDE development environment you could download Microsoft's free Visual Studio Express C++.
Either way you'll likely have to convert some of the function calls to use Windows specific APIs (if you want a book I'd also recommend the Hart book mentioned in mrjoltcola's answer). For simple command line tools this conversion is usually not a huge deal, the big porting nightmares tend to involve tools with GUIs which have deep embedded dependencies on the GUI framework provided by the OS.

Resources