MinGW GCC Not Recognizing MEMSTATUSEX? - c

I am using MinGW GCC compiler on Windows 7. I am trying to compile source that contains the following code:
MEMORYSTATUSEX mem_stat;
mem_stat.dwLength = sizeof(memstat);
BOOL success = GlobalMemoryStatusEx(mem_stat);
ram_ptr = &(mem_stat->ullAvailPhys);
As I'm sure you can guess, this code simply gets the available memory using the MEMORYSTATUSEX struct returned by GlobalMemoryStatusEx.
When I try to compile, I get this error:
error: unknown type name 'MEMORYSTATUSEX'
I looked in winbase.h (in the MinGW installation include folder) and guess what I found?
#if (_WIN32_WINNT >= 0x0500)
typedef struct _MEMORYSTATUSEX {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORDLONG ullTotalPhys;
DWORDLONG ullAvailPhys;
DWORDLONG ullTotalPageFile;
DWORDLONG ullAvailPageFile;
DWORDLONG ullTotalVirtual;
DWORDLONG ullAvailVirtual;
DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX,*LPMEMORYSTATUSEX;
#endif
So it's there. I'm guessing this has something to do with the precompiler if/endif, but I don't how to fix that....
Also what's even more bizzare is that if I use the MEMORYSTATUS struct instead, it works fine.
According to the MS docs, both have the same minimum client version requirement:
MEMORYSTATUSEX:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366589%28v=vs.85%29.aspx
MEMORYSTATUS:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366772%28v=vs.85%29.aspx
Is there some compiler flag I need to set? Or does anyone have any other solutions?
Thanks in advance for your help!

Before including Windows.h, add :
#define WINVER 0x0500
The header file windef.h says :
/*
* If you need Win32 API features newer the Win95 and WinNT then you must
* define WINVER before including windows.h or any other method of including
* the windef.h header.
*/
and then compile with the -std=c++11 flag like :
g++ -Wall -std=c++11 -c <yourFile>.cpp -o <yourFile>.o

Apparently you have to define _WIN32_WINNT yourself either as a compiler flag or definition statement in one of your header/source files for this particular function to work properly.
Adding the #define _WIN32_WINNT 0x0500 will allow the code to compile normally.

Related

WinApi Commctrl trackbar identifier undeclared

I'm trying to handle a trackbar notification, but for some reason my GCC compiler complains that the TRBN_THUMBPOSCHANGING identifier is undeclared.
I have included the header,
#include <commctrl.h>
and initialised the controls,
INITCOMMONCONTROLSEX icex;
icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_WIN95_CLASSES;
InitCommonControlsEx(&icex);
I have also tried ICC_BAR_CLASSES and a few others instead of the win95 one.
Also I'm compiling via bat file including this command
gcc foodplaner.o resources.o sqlite3.o -lgdi32 -lcomctl32 -o foodplaner.exe
Creating the trackbar was no problem, it shows up and can be controlled.
What am I missing?
TRBN_THUMBPOSCHANGING is available in Windows Vista and above. To use it you have to set _WIN32_WINNT to the minimum supported version of your application prior to including any header files. This can be done in code
#define _WIN32_WINNT 0x0600 // Windows Vista
or on your compiler's command line (-D_WIN32_WINNT=0x0600). The latter is recommended to prevent introducing any mismatches. See Using the Windows Headers for details.

Error compiling HDF5 with MinGW and CMake

I'm trying to compile HDF5 with MinGW's gcc 4.8.1 and CMake. I followed the instructions in the INSTALL_CMake documentation for Windows and read everything that I found on Google but I still get the following errors:
In file included from c:\mingw32-xy\include\fcntl.h:37:0,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5private.h:53,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5detect.c:57:
c:\mingw32-xy\include\io.h:301:1: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int, off64_t, int);
^
c:\mingw32-xy\include\io.h:301:36: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int, off64_t, int);
^
c:\mingw32-xy\include\io.h:302:1: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
^
c:\mingw32-xy\include\io.h:302:39: error: unknown type name 'off64_t'
__CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
^
In file included from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5private.h:70:0,
from C:\Users\jicervan.NDC\Downloads\hdf5-1.8.13\hdf5-1.8.13\src\H5detect.c:57:
c:\mingw32-xy\include\unistd.h:65:20: error: unknown type name 'off_t'
int ftruncate(int, off_t);
The errors and warnings go on and on with a long list of warnings and undefines. Does anybody has any suggestions on how to solve this problem? Are there any other alternatives like using the Visual Studio binaries with MinGW maybe?
I finally got it working. My first attempt was to use configure and make according to the documentation in the /release_docs/INSTALL_MinGW.txt file, but it didn't work. I ended up using CMake. For documentation purposes, here's the procedure that I followed:
OPERATING SYSTEM: Windows 8.1 pro
COMPILER: CMake + MinGW gcc version 4.8.1
HDF5 VERSION: 1.8.13
STEPS:
Uncompress the hdf5-1.8.13.zip file.
Download CMake, and run the GUI.
Set the source folder to <hdf5-location>/hdf5-1.8.13 and the build folder to the folder where you want to place your Makefile.
Click on Configure, and a pop-up window will appear. Choose the MinGW Makefiles option as the generator for your project, and select the Use default native compilers option.
Once the list is populated with options, leave the default checkboxes selected, and also select BUILD_SHARED_LIBRARIES. Now the fun begins; compiling.
Locate the file H5pubconfig.h file in your HDF5 build folder and append the following lines:
// Define Windows 32
#ifndef H5_HAVE_WIN32_API
#ifdef WIN32 /* defined for all windows systems */
#define H5_HAVE_WIN32_API 1
#endif
#endif
// Define MinGW
#ifndef H5_HAVE_MINGW
#ifdef __MINGW32__ /*defined for all MinGW compilers */
#define H5_HAVE_MINGW 1
#endif
#endif
// Redefine _In_ and _Out_ to empty values
#define _In_
#define _Out_
// Redefine off_t and off64_t to match io.h and unistd.h
#define off_t _off_t
#define off64_t _off64_t
On the file io.hlocated in <MyFolder>/MinGW32/include/ change every instance of off64_t to _off64_t.
On the file unistd.hlocated in <MyFolder>/MinGW32/include/ change every instance of off_t to _off_t.
On the MinGW/MSYS command prompt, change directory to the location of your HDF5 Makefile (set on step 3).
Type the command Make and verify that it's compiled correctly.
Don't forget to include the flags -I/<your-HDF5-build-folder>/include/, -L/<your-HDF5-build-folder>/bin/, and -lhdf5 when you compile. Happy coding.

PostgreSQL: compile C function on Windows 8 64bit

I'm learning how to compile a C trigger to load on PostgreSQL
When compile the "trigf.c" (in the example at http://www.postgresql.org/docs/9.3/interactive/trigger-example.html), I get some issue related to int64 error (c.h header)
#ifdef HAVE_LONG_INT_64
/* Plain "long int" fits, use it */
#ifndef HAVE_INT64
typedef long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long int uint64;
#endif
#elif defined(HAVE_LONG_LONG_INT_64)
/* We have working support for "long long int", use that */
#ifndef HAVE_INT64
typedef long long int int64;
#endif
#ifndef HAVE_UINT64
typedef unsigned long long int uint64;
#endif
#else
/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */
#error must have a working 64-bit integer datatype
#endif
-> [Error] #error must have a working 64-bit integer datatype
I don't know how to solve that problem, because clearly that there is a working 64 bit integer datatype that I can use.
Edit: I installed pgsql from binary. The C compiler I used for compile the C function file is MinGW GCC 4.7.2. (Using the path of Dev-cpp mingw gcc).
The command line is :
gcc -fpic -c "D:\trigf.c"
At the first time, it showed an error that in c.h: not found libintl.h (no such file or directory). Then I download the Lib Intl - 0.14.4 (library for native language support). The installation create a folder: C:\Program Files (x86)\GnuWin32.
I edited the environment variable CPATH, added C:\Program Files (x86)\GnuWin32\include folder, which contained libintl.h.
I ran the command again, and I met with the above error.
Update: It turns out not to be too hard to build extensions stand-alone with MSVC on Windows. I wrote a blog post detailing the process today.
The usual way to build extensions on Windows is to do it inside a working PostgreSQL build tree.
See these instructions on the PostgreSQL wiki.
You might be able to do it using MinGW and PGXS using a suitable Makefile instead.
Just trying to compile a standalone .c file is unlikely to work as there are a variety of paths and preprocessor definitions required.
It doesn't help that the current PostgreSQL packages don't include headers for public dependencies, which is really rather frustrating. You can safely compile without ENABLE_NLS defined even if the target PostgreSQL was built with ENABLE_NLS, though, and in this case libintl.h won't be required.

Why multiple definitions? Why are other references not defined? This is really basic, what am I missing?

I have a small project that I need to compile. I have one header and one source that I have created and a nearly empty driver.c that includes my header.
Observe:
// iol.h
#ifndef __IOL_HEADER
#define __IOL_HEADER
/* program: iol.h
date: 5 October 2010
*/
#define UNIX 1
#define WINDOWS 2
#define OS UNIX
#if OS == UNIX
#include <ncurses.h>
#elif OS == WINDOWS
#include <conio.h>
#include <windows.h>
// Function declarations!
#endif
void iol_init(void);
#endif
Now my implementation file:
// iol.c
#include <string.h>
#include <stdlib.h>
#include "iol.h"
void iol_init(void) {
#if OS == WINDOWS
/* no startup required for windows */
#elif OS == UNIX
initscr();
noecho();
cbreak();
keypad(stdscr, 1);
// Implmntn continues....
Now the driver that includes my header and provides the main ():
//main.c
#include "iol.h"
My bash command:
gcc iol.c driver.c -l"ncurses"
I get back:
/tmp/ccmmW6hQ.o:iol.c:(.text+0x83f): first defined here
/tmp/ccwIKUaT.o: In function 'isEscaping':
driver.c:(.text+0xbab): multiple definition of 'isEscaping'
/tmp/ccmmW6hQ.o:iol.c:(.text+0xbab): first defined here
/tmp/ccwIKUaT.o: In function 'initSeq':
..
driver.c:(.text+0x149): undefined reference to 'iol_prnstr'
driver.c:(.text+0x178): undefined reference to 'iol_putch'
..
driver.c:(.text+0x726): undefined reference to 'iol_display'
collect2: ld returned 1 exit status
I just want to get to point where I can compile this, and start ripping my hair out 'cuz of all my seg-faults. What's the problem in my setup? I RTFM on the Gnu C Compiler apparently I'm doing what I'm supposed to, which is declare stuff in iol.h, define in iol.c, and use it in driver.c this is pretty trivial stuff maybe I just need a second set of eyes :S
I'm actually getting a long list of errors, if anyone thinks that's relevant, I'm happy to post the whole source.
this is the linker complaining. This is what you would get if you had a function defined in the header file that was not declared 'inline'
the missing ones are because you have not added the correct libraries
Try compiling them separately:
$ gcc -Wall -c ioi.c
$ gcc -Wall -c driver.c
$ gcc ioi.o driver.o -o program -lncurses
To isolate and fix compilation errors...
You didn't mention if you are compiling on Windows or Unix. If on Windows I suspect that there are order dependencies in the .h files. Usually you want windows.h first so that it defines constants that the other .h files will use.

Link error for Windows functions

I'm trying to test if standard library (kernel32.dll) have one of the function.
Code snippet for test:
extern void CreateProcessA (void);
int
main (void)
{
CreateProcessA ();
return 0;
}
The code compiles and links as follow:
cl /c test.c
link test.obj kernel32.lib
This code can be compiled well with Visual C++, but cannot link:
test.obj : error LNK2019: unresolved external symbol _CreateProcessA referenced in function _main
But function CreateProcessA does exists in kernel32.dll, you no?
How to link it properly?
P.S. I don't want to run this code, just check that function exists (if code compiles and links - function exists).
To see if the function exists, you use
dumpbin /exports kernel32.dll | findstr CreateProcess
You didn't even use the right prototype, so of course the linker can't find the correct function. The naming convention is completely off, and CreateProcess is really a macro (that expands to either CreateProcessA or W depending on UNICODE).
(You don't need to link against kernel32.lib explicitly as that's already done by default by cl.exe)
Instead of declaring the prototype yourself, #include <windows.h>.
Kernel32.dll exports the function as "CreateProcessA", note the missing leading underscore. The only way to convince the linker to use that export is by linking kernel32.lib, an import library supplied by the Windows SDK.
You'll then run into the next problem, the import library declares the export as _CreateProcess#40. This is a name decoration applied by the __stdcall calling convention. That calling convention was explicitly designed to catch your mistake, you didn't declare the function properly. The #40 part of the name indicates the number of bytes needed in the stack frame to pass the arguments.
So, to make it work you should #include <windows.h> to get the proper function declaration and link kernel32.lib to get the proper export name.
Right now you are declaring your own version of CreateProcess(). Since you did not provide the body (code), the linker doesnt know where to check to find the function to execute.
In order to call CreateProcess from kernel32.lib, you need to include the proper headers
#include <windows.h>
If the compiler doesnt know windows.h then probably Platform SDK for windows isnt installed correctly.
you will also need to link with the proper lib
#pragma comment(lib, "kernel32.lib")
You should also read the documentation about createprocess since it takes a gazillion of parametetrs
BOOL WINAPI CreateProcess(
__in_opt LPCTSTR lpApplicationName,
__inout_opt LPTSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCTSTR lpCurrentDirectory,
__in LPSTARTUPINFO lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
You should search for CreateProcess examples across the interwebs and maybe consider switching to c++ since you're on windows
For starters, put in a proper header file for the prototypes, <windows.h>, as this is a Windows source, add the kernel32.lib for your linker, remove that prototype as it is incorrect. Your main function is debatable as to whether you are creating a command line program or a windows program - if it is the latter, that should read 'WinMain'.
If you look in the MSDN for the function 'CreateProcess', scroll down and you will see the 'Library', that is the hint to tell you which library you need to link for it to work properly.
Hope this helps,
Best regards,
Tom.
I think this is a bad idea, but if you want to do it, you need to link with the kernel32.lib export library.
You must include windows.h in order to get the correct prototype:
#include <windows.h>
int
main (void)
{
CreateProcess(); // will cause warning due to incorrect parameter list
return 0;
}
Is there a particular reason you don't want to include windows.h?
Using MinGW one can use the "-mwindows" flag. Example:
gcc.exe -c -g -MMD -MP -MF build/Debug/MinGW-Windows/newmain.o.d -o build/Debug/MinGW-Windows/newmain.o newmain.c
gcc.exe -o dist/Debug/MinGW-Windows/hwprint_dll build/Debug/MinGW-Windows/newmain.o -mwindows
This will include stuff like gdi32.a, kernel32.a, user32.a and ws2_32.a.

Resources