Как мне скомпилировать программу Window API, используя cl? - PullRequest
5 голосов
/ 08 февраля 2012

Я пытаюсь скомпилировать простую программу C Windows API с помощью командной строки Windows SDK.

Вот выдержка из программы:

#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);

[...]

Когда я компилирую ее с помощью

cl test.c

в командной строке Windows SDK, он дает мне много ошибок компоновщика, таких как:

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

Ответы [ 2 ]

17 голосов
/ 08 февраля 2012

Есть как минимум две проблемы.

  1. Компоновщик сообщает вам, что существует "неразрешенный внешний символ".Это означает, что он не может найти определение для функции (функций), которую вы пытались вызвать.В этом случае есть две такие неопределенные функции: CreateWindowExA и RegisterClassA.

    Очевидно, что определение этих функций находится не в вашем коде, а в библиотеках API Windows, так что выВам нужно будет сообщить компоновщику, где он может найти эти определения.

    SDK поставляется с файлами-заглушками (*.lib), которые содержат информацию, используемую компоновщиком, чтобы он мог найти правильные определения функций вWindows DLL во время выполнения.Вам нужно указать компоновщику, где он может найти эти *.lib файлы.

    Для этого есть несколько различных стратегий:

    1. Простой (хотя и не-портативный) способ - вставить оператор #pragma в исходный файл, который указывает компилятору оставить комментарий, распознаваемый компоновщиком.Например,

      #pragma comment(lib, "user32")
      

      автоматически связывается с user32.lib, который является заглушкой для user32.dll.

    2. В качестве альтернативы, вы можете передать параметры вкомандная строка до cl.exe.Это очень сложно, если вы спешите, если вы не используете MSBuild или какой-то другой make-файл.В этом случае вам потребуется изменить (как минимум) командную строку:

      cl test.c user32.lib
      

    Обе эти опции, естественно, предполагают, что каталог Windows SDK был добавлен в путь.Я почти уверен, что установщик сделает это автоматически, но я не уверен.Если это не так или вы удалили эти файлы из своего пути, вам нужно будет использовать полные пути к файлам *.lib в командной строке.

    Чтение документациидля возможных опций компилятора - хорошее место для начала.Или еще лучше, если вы не знакомы с программированием Windows, используя среду, подобную Visual Studio, которая автоматически собирает все эти вещи для вас .Как только вы поймете, что происходит, посмотрите, что представляет собой командная строка, которую запускает Visual Studio, и разбейте ее побитно.

  2. Следующая проблема заключается в том, что вы компилируете без Определен Unicode, и поскольку ANSI является значением по умолчанию , все макросы в заголовочных файлах Windows разрешают вызывать суффиксные версии A всех функций SDK.Это, вероятно, не то, что вы хотите.Windows была полностью Unicode уже более десяти лет, и все новые приложения должны быть построены как Unicode.Версии Unicode имеют суффикс W, добавленный к их имени.

    Опять же, вы можете указать компилятору явно создавать Unicode, либо добавляя строки в ваш исходный файл, либо добавляя параметры в вашу командную строку.

    В этом случае, возможно, самый простой способ - просто добавить

     #define UNICODE
    

    в начало исходного файла перед #include <windows.h>.Как мы видели выше, из среды Visual Studio UNICODE автоматически определяется для вас, если вы явно не измените настройки своего проекта, чтобы настроить его на что-то другое.

16 голосов
/ 08 февраля 2012

Эти функции находятся в user32.lib. Вы должны предоставить это инструменту cl.

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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...