0

I am trying to compile some WinAPI code using gcc compiler. However whenever I call functions like CreateSemaphoreEx, CreateMutexEx (and some other Ex functions) I get "undefined reference to 'CreateSemaphoreEx'" link error. It works with CreateSemaphore or CreateMutex but not the Ex versions of these functions.

First I compiled with mwindows flag as such (gcc main.c -mwindows) Then I tried linking to the library manually (gcc -lkernel32 main.c) I have also tried using CreateSemaphoreExA

I also tried uninstalling and reinstalling mingw-w64 and even tried switching to TDM-GCC

I know if I change it to CreateSemaphore call it works, however I want to use the Ex version.

#include <windows.h>

int main(int argc, char** argv)
{
    int initial_count = 0;
    int maximum_count = 5;

    HANDLE semaphore = CreateSemaphoreEx(0, initial_count, maximum_count, NULL, 0, SYNCHRONIZE | SEMAPHORE_MODIFY_STATE);
}

How can I get access to these WinAPI functions using gcc compiler on Windows (if it is at all possible).

-------- Complete Compiler Output ---------

main.c: In function 'main':
main.c:8:21: warning: implicit declaration of function 'CreateSemaphoreEx'; did you mean 'CreateSemaphoreA'? [-Wimplicit-function-declaration]
  HANDLE semaphore = CreateSemaphoreEx(0, initial_count, maximum_count, NULL, 0, SYNCHRONIZE | SEMAPHORE_MODIFY_STATE);
                     ^~~~~~~~~~~~~~~~~
                     CreateSemaphoreA
main.c:8:21: warning: initialization of 'HANDLE' {aka 'void *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
C:\Users\Nexwave\AppData\Local\Temp\cc3ncRYX.o:main.c:(.text+0x49): undefined reference to `CreateSemaphoreEx'
collect2.exe: error: ld returned 1 exit status

Edit 1: I know about linking. My question is whether the kernel32 library used by mingw-w64 different than one used by Microsoft's linker. And if it is different then why is there no definition for CreateSemaphoreEx (and some other Ex functions) that are available in the actual Kernel32.lib

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Have a look [here](https://stackoverflow.com/questions/22426574/gcc-undefined-reference-to); maybe it helps. – Jeroen Heier Jun 21 '19 at 04:58
  • The actual function is CreateSemaphoreExA (or W). CreateSemaphoreEx should be defined as a macro. For some reason you are not getting the macro. – user253751 Jun 21 '19 at 05:06
  • I have tried using both CreateSemaphoreExA and CreateSemaphoreExW. I have also check the header file and the macro that defined CreateSemaphoreEx is there. There is some problem with the linking or the underlying library. – KhanSuhaib Jun 21 '19 at 05:24
  • this mean that lib (*kernel32*) which you use not containing *CreateSemaphoreEx[A|W]* symbol – RbMm Jun 21 '19 at 05:28
  • That was my guess but this works fine with MSVC compiler. Also https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createsemaphoreexa this reference mentions that the function definition is available in kernel32.lib – KhanSuhaib Jun 21 '19 at 05:30
  • @KhanSuhaib - MSVC compiler (*cl.exe*) not do linking. this done by absolute another tool - *link.exe*. in *kernel32.lib* (if it yet not for *xp*) exist *__imp_CreateSemaphoreEx[A|W]* symbol. but in your *kernel32* this symbol not exist. simply search it manually here – RbMm Jun 21 '19 at 05:35
  • @RbMm ya I incorrectly stated that the compiler does that. But when I am compiling the same file using the command cl main.c (instead of gcc main.c -mwindows) the program works So it isn't a problem with the kernel32.lib. I was wondering whether the kernel32.lib used by gcc and the one used by Microsoft's linker are different. – KhanSuhaib Jun 21 '19 at 05:49
  • Please copy and paste the complete compiler output – M.M Jun 21 '19 at 06:00
  • @M.M added the entire compiler output – KhanSuhaib Jun 21 '19 at 06:05
  • @KhanSuhaib "*I was wondering whether the kernel32.lib used by gcc and the one used by Microsoft's linker are different*" - obviously yes, they are. So, either update gcc with a newer SDK, use MSVC, or load the `Ex` functions dynamically at runtime using `GetProcAddress()` instead of linking to them statically – Remy Lebeau Jun 21 '19 at 07:22
  • Is there a reason to use GCC in Windows? – Michael Chourdakis Jun 21 '19 at 08:29
  • @MichaelChourdakis it's one of the better compilers , and always up to date – M.M Jun 21 '19 at 10:59
  • `CreateSemaphoreEx` is only available since Vista, and that's why you need to `#define _WIN32_WINNT 0x0600`. – ssbssa Jun 21 '19 at 11:16
  • @KhanSuhaib can you also give the OS version you are using, the output of `gcc -v`, and the output when you try `CreateSemaphoreExA` or `CreateSemaphoreExW` – M.M Jun 21 '19 at 11:16
  • @M.M. You don't only need a compiler, you need an IDE, a debugger, and proper documentation. – Michael Chourdakis Jun 21 '19 at 14:07
  • @MichaelChourdakis I use QtCreator/MSYS2 which works fabulously . Not sure what documentation you refer to but the C standard documents C; the MS websites document the WinAPI, Qt document their own libraries, etc. – M.M Jun 21 '19 at 23:54
  • @ssbssa this works. For some reason I kept thinking this was a link error. I am on Windows 10 using VS2019 and latest version of mingw-w64. So can you explain why I didn't need to use that define when using microsoft's compiler by need it when using mingw-w64 – KhanSuhaib Jun 22 '19 at 03:52
  • See [Modifying WINVER and _WIN32_WINNT](https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=vs-2019): `By default, Win32 projects in Visual Studio 2017 use the Windows 10 SDK.` So I guess `_WIN32_WINNT` is already defined in the VS project settings. – ssbssa Jun 22 '19 at 12:40

1 Answers1

0

The problem indicated by the first diagnostic:

implicit declaration of function 'CreateSemaphoreEx'

The other errors are cascading from that. In general you should always fix the first compiler diagnostic before worrying too much about the others.

Note, I would recommend using standard compiler switches so that it says "error" instead of "warning" for this error condition, and breaks compilation. Some people see the word "warning" and think "oh it's just a warning and not important, I'll ignore it" but that would be a mistake in this case.


The error message above means that your system headers do not define CreateSemaphoreEx. Why is this? Here are the main possibilities:

  • You're on an old version of Windows; the function was added in Windows Vista and will not be accessible if you're on XP for example. (The Windows headers don't define the prototype and macro if the system is detected as being pre-Vista).
  • You're using an old version of mingw-w64 that doesn't have this function.
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Note: will update answer when OP gives more detail as requested in comments – M.M Jun 21 '19 at 11:20
  • I was incorrectly believing that this was a link error. Using #define _WIN32_WINNT 0x0600 before including windows.h header file as suggested by @ssbssa solves the problem. – KhanSuhaib Jun 22 '19 at 03:56
  • @KhanSuhaib unless you have an extremely old version of the compiler, that value should already be defined correctly, so there might still be some other issue going on. Also using that value will disable any functions that were added after Vista – M.M Jun 23 '19 at 04:24