How to compile Window API program with cl?

I am trying to compile a simple Windows API C program using the Windows SDK command line.

Here is an excerpt from the program:

#include <Windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { [...] RegisterClass(&wc); hwnd = CreateWindow("test", NULL, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); [...] 

When I compile it with

 cl test.c 

at the Windows SDK Command prompt, this gives me a lot of linker errors, such as:

 test.obj : error LNK2019: unresolved external symbol __imp_CreateWindowExA referenced in function WinMain test.obj : error LNK2019: unresolved external symbol __imp_RegisterClassA referenced in function WinMain 
+4
source share
2 answers

These functions live in user32.lib. You must provide this for the cl tool.

 cl test.c ""C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\user32.lib" Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.307 Copyright (C) Microsoft Corporation. All rights reserved. test.c Microsoft (R) Incremental Linker Version 9.00.30729.01 Copyright (C) Microsoft Corporation. All rights reserved. /out:test.exe test.obj "C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\user32.lib" 
+15
source

There are at least two problems.

  • The component tells you that there is an "unresolved external symbol." This means that it cannot find a definition for the function (s) that you tried to call. In this case, there are two such undefined functions: CreateWindowExA and RegisterClassA .

    Obviously, the definition of these functions is not contained in your code, but rather in the Windows API libraries, so you need to tell the linker where it can find these definitions.

    The SDK comes with stub files ( *.lib ) that contain information used by the linker so that it can find the correct function definitions in the Windows libraries at run time. You need to instruct the linker where it can find these *.lib files.

    There are several different strategies for this:

    • A simple (though not portable) way is to insert the #pragma instruction in the source file, which instructs the compiler to leave a comment recognized by the linker. For instance,

       #pragma comment(lib, "user32") 

      automatically refers to user32.lib , which is a stub file for user32.dll .

    • Alternatively, you can pass parameters on the command line cl.exe . This is terribly difficult in a hurry, although if you are not using MSBuild or some kind of make file. In this case, you will need to change your command line to (at least):

       cl test.c user32.lib 

    Both of these options naturally assume that your Windows SDK directory has been added to the path. I'm sure the installer will do this automatically, but I'm not sure. If this is not the case, or you deleted these files from your path, you will need to use the fully qualified paths to the *.lib files on the command line.

    Reading the documentation for possible compiler options is a good place to start. Or even better if you are not familiar with Windows programming using an environment such as Visual Studio, which automatically combines all of these materials for you automatically . After you understand what is going on, look at what works on the command line that Visual Studio runs and analyze it bit by bit.

  • The next problem is that you are compiling without Unicode, and because by default ANSI , all macros inside the Windows header files allow all SDK functions to be called with suffixed versions A This is probably not what you want. Windows has been fully running Unicode for more than a decade, and all new applications should be built as Unicode. In Unicode versions, the suffix W added to their name.

    Again, you can instruct the compiler to build using Unicode explicitly by adding lines to the source file or adding parameters to your command line.

    In this case, the easiest way is probably just to add

      #define UNICODE 

    to the beginning of the source file before #include <windows.h> . Just as we saw above, from Visual Studio, UNICODE automatically detected for you if you do not explicitly change the settings of your project in order to target something else.

+16
source

Source: https://habr.com/ru/post/1395456/


All Articles