Link User32 with gcc - c

I have a C program which has a function call that is defined in windows.h (which I have included), however, when I try and compile it with gcc, I get the error:
warning: implicit declaration of function `LockWorkStation'
I looked at the MSDN documentation and I see that this function is the User32 library file, and I was wondering how I would go about linking that to my file.

LockWorkstation is available on Windows 2000 and up. You have to declare the version of Windows you are targeting. Make it look like this:
#define _WIN32_WINNT 0x500
#include <windows.h>

I have the same problem with gcc - but this is not a linker error. The message means that there is no prototype for the function in winuser.h, or more accurately the compiler can't find such a prototype. That is because the relevant bit of winuser.h looks like this:
#if (_WIN32_WINNT >= 0x0500)
WINUSERAPI BOOL WINAPI LockWorkStation(void);
#endif
In other words, you need a version of Windows >= 5 (i.e Win2K) to use this function. I'm currently trying this on Win2K and it doesn't work, which indicates the macro is not being set correctly. I don't do much "real" Windows programming these days, so I'm not sure why that should be.
Edit: In fact, a bit of experiment indicates that gcc thinks the Windows version of Win2K (on my installation at least) is 0x0400.
Further: Actually, the macro _WIN32_WINNT is (as the leading underscore suggests) a reserved name in C and C++, and should not be defined in user code. Defining the macro WINVER seems to have the same effect, and is (conceptually at least) more portable. This code compiles on my gcc installation:
#define WINVER 0x0500
#include <windows.h>
int main() {
LockWorkStation();
}

Related

checking whether library exist via preprocessor

There are two libraries zconf.h and unistd.h which are used to at least to get pid of the process. I generally test my code on Mac OSX and Ubuntu 18.04 in which they use zconf.h preferably(compiler offers zconf.h in lieu of unistd.h) if I forget to add, then if the code works, it's ok. However, in some prior day I needed to test the code in another machine AFAIR it has Ubuntu 10 or 12. Its compiler complained that there is no zconf.h. I wonder whether there is a way to check a machine has zconf.h, if not, use unistd.h. Can it be done using preprocessors like,
#ifdef ITS_IF_CONDITION
#include <zconf.h>
#else
#include <unistd.h>
Newer versions of GCC, clang and MSVC compilers implement the __has_include feature. Although it's a C++ 17 feature, I believe all three support it in plain C too.
But the traditional (and probably more portable) way is to check the existence of include files in a config script before the build process. Both autoconf and cmake have ways to achieve this.
#ifdef __has_include
#if __has_include(<zconf.h>)
#include <zconf.h>
#else
#include <unistd.h>
#endif
#else
#include <unistd.h>
#endif

Compiler ignores #define _GNU_SOURCE

I am not a native english speaker, so please excuse any spelling or grammar mistakes
I am not a compiling expert, nor do I have any useful experience with builds and their errors
I am C# programmer and mainly working in an MS Enviroment
I only know the 3 "must know to survive in Linux commands" "./configure, make & make install" from my little Linux Experience
My Development Enviroment
I am using a Windows 7 Workstation
with Cygwin and MinGW (as Linux 'Replacement') to compile.
The Problem
I want to compile C source code on windows, which is primary written for Linux distributions.
/Configure works without problems.
If I use the command make to compile the sources, I run into following error:
Error
grib_keys.c:50:34:
error: 'alphasort' undeclared (first use in this function)
Research:
My Research proved me, that this problem already has been solved, but unfortunately, the answer isn't working for me.
Implicit declaration of scandir; alphasort is undeclared
http://ubuntuforums.org/archive/index.php/t-1653576.html
The solution says, that I only have to include following: #define _GNU_SOURCE
Which I tried, but as already stated, it doesn't work.
I included it in following files:
- grib_keys.c
- config.h
and tried to compile them with concurrent and not concurrent inclusion.
In the end, the important parts of the files looked like this:
config.h
********
/* Add #define _GNU_SOURCE to solve "'alphasort' undeclared" error */
#define _GNU_SOURCE
grib_keys.c
***********
#define _GNU_SOURCE
count = scandir(dir, &files, 0, alphasort);
What I want to achive & to know:
I want to compile the whole sourcecode of below named API, to use the binaries on a windows operating system.
Also I would like to know, whether I wrote the "#define _GNU_SOURCE"-Tag to the right place, or if I made a mistake.
Downloads:
Api
https://software.ecmwf.int/wiki/display/GRIB/Home
If you're going to declare feature-test macros such as _GNU_SOURCE, you must ensure that the preprocessor sees them before it sees any code that uses them. That generally means they have to be processed before any system headers. The best placement, therefore, is at the top of each of your C source files (not headers), before any #include directives.
With that said, you need a solution that applies to the C library you're actually using, and its development headers. For MinGW, it seems that would be Microsoft's C library, which does not appear to document an alphasort() function.
Even if you were using glibc (Cygwin's version, for instance) my glibc docs claim that the needed feature-test macro for alphasort() is either _BSD_SOURCE or _SVID_SOURCE, not _GNU_SOURCE. Since glibc 2.10, it looks like it's probably best to use _POSIX_C_SOURCE >= 200809L, or _XOPEN_SOURCE >= 700, as these reflect the fact that the function was standardized in POSIX.1-2008.

Gcc and g++ different on write()

#include <sys/syscall.h>
#define BUFSIZE 1024
main()
{
char buf[BUFSIZE];
int n;
while((n=read(0,buf,BUFSIZE))>0)
write(1,buf,n);
return 0;
}
When I compile this by using gcc, it is fine.
But use g++ I got :
inandout.c:7:32: error: ‘read’ was not declared in this scope
while((n=read(0,buf,BUFSIZE))>0)
^
inandout.c:8:22: error: ‘write’ was not declared in this scope
write(1,buf,n);
^
Why is that?
This is because gcc is a C compiler, g++ is a C++ compiler, and C and C++ are different languages.
If you want to compiler that source code as C++ program, you must change it to become C++. For example, there are no implicit function declarations in C++, so you must include unistd.h for read() and write() declarations. You also don't need syscall.h header.
Also, it is only that simple because you have a simple code snippet. Porting C code to C++ could be a nightmare as there are ~ 50 differences and in some cases code compiles well in both cases, but behaves differently.
P.S.: And instead of defining weird BUFSIZE yourself, consider using standard BUFSIZ :)
You Just need to add include <unistd.h>
C defaults functions that do not have a prototype to a function that returns an int - but you should have got warnings for that (did you use -Wall?).
C++ doesn't allow that, you need to include the correct header file, unistd.h, which you should also do in C.
I upgraded to gcc 4.8.5. In version 4.7 the compiler stopped including unistd.h in a number of include files. This is why older gcc compiler versions worked without including unistd.h.
https://gcc.gnu.org/gcc-4.7/porting_to.html
"C++ language issues
Header dependency changes
Many of the standard C++ library include files have been edited to no longer include unistd.h to remove namespace pollution. "
In my case I got ::write has not been declared when I included stdio.h, but my previous gcc version 4.4 compiled fine. This is a useful command to see what paths are being searched by the preprocessor: g++ -H test.cpp

C macro for OS X version (Lion or not) detection?

Is there a predefined C macro for detecting the version of OS X? I know __APPLE__ and __MACH__ exist, but those are binary. Is there a specific value for __APPLE_CC__ that indicates Lion?
In particular, Lion added a definition of getline() to <stdio.h> in Lion and it would be nice to be able to detect whether or not code was compiling on Lion or not to work around compilation errors.
Specifically, I'm referring to building Unix C code in Bash (outside of XCode).
The Availability.h macros allow you to check for compile- and run-time version dependencies. See the discussion here.
Check in /usr/include/AvailabilityMacros.h - it contains macros such as:
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER DEPRECATED_ATTRIBUTE
#else
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
#endif
I came across this stuff because 'openssl/sha1.h' has been slathered with 'deprecated' attributes for Lion, so compiling git gets warnings galore.

Oracle's pro*C compiler and gnu C (__builtin_va_list, __attribute__, etc)

I'm compiling a database library with proC which converts the .ppc library file to a .c file that gcc can use. However, I'm getting a lot of errors in proC like the following
PCC-S-02201, Encountered the symbol
"__ attribute__ " when expecting one of
the `following`
...
, Encountered the symbol
"__builtin_va_list" when expecting one of
the `following`
The missing symbols are from a chain of standard includes like stdio.h and stdlib.h. How do I get around this issue?
The library I'm compiling came from an old solaris system that we're now upgrading (to a new solaris 10 system) and the header files don't seem to use these symbols. e.g. the newer .h files has
typedef __builtin_va_list va_list
while the old .h files has
typedef void* va_list
There are a lot of things like this so I'm reluctant to go and fix all of them manually with a typedef
Change PARSE param in your $ORACLE_HOME/precomp/admin/pcscfg.cfg to PARTIAL - it will use more relaxed C parsing so Pro*C don't bitch about C syntax it doesn't understand.
You can achieve it also by including this preprocessor directive. Pro*C evaluates macros and replaces them
#ifdef ORA_PROC
#define __attribute__(x)
#endif
I'm actually at home and can't verify exactly how it is defined in our code base, I will check it and complete it but it is like the above.
Update: so the exact code we use in our project is:
#if defined(ORA_PROC) || !defined(__GNUC__)
#define __attribute__(x)
typedef unsigned long long uint64_t;
typedef long long int64_t;
#define INLINE
#endif
For an unknown reason the preprocessor is unable to have 64 bits types defined so I define them directly so that it works.
Our project is on Solaris 9 for SPARC and we compile with GCC 3.3.1 and GCC 3.4.2 and we use Oracle 10g

Resources