Wie kann ich kompilieren ein Fenster-API-Programm mit cl?
Ich versuche zu kompilieren eine einfache C-API-Windows-Programm mit dem Windows SDK-Eingabeaufforderung.
Hier ein Auszug aus dem Programm:
#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);
[...]
Wenn ich es kompilieren mit
cl test.c
in der Windows SDK-Befehl Promt, es gibt mir eine Menge von linker-Fehler wie diese:
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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese Funktionen live in user32.lib. Sie liefern müssen, dass die cl-tool.
Gibt es mindestens zwei Probleme.
Dem linker sagen, dass es ein "nicht aufgelöstes externes symbol". Das bedeutet, dass es nicht finden können, eine definition für die Funktion(en), die Sie versuchte zu rufen. In diesem Fall gibt es zwei solche Undefinierte Funktionen:
CreateWindowExA
undRegisterClassA
.Offensichtlich ist die definition für diese Funktionen steht nicht im code, sondern in der Windows-API-Bibliotheken, so dass Sie werden müssen informieren die linker von denen, die es finden kann diese Definitionen.
Das SDK kommt mit stubs (
*.lib
) - Dateien, die Informationen enthalten, die vom linker verwendet, so dass Sie finden können die richtige Funktion von Definitionen in der Windows-DLLs zur Laufzeit. Sie müssen, weisen Sie den linker, wo Sie es finden kann*.lib
- Dateien.Gibt es ein paar verschiedene Strategien dafür:
Den einfachen (wenn auch nicht tragbare) Weg ist das einfügen eines
#pragma
- Anweisung in der Quelldatei, das weist den compiler an, einen Kommentar hinterlassen, anerkannt durch den linker. Zum Beispiel,automatisch links zu
user32.lib
, die die stub-Datei füruser32.dll
.Alternativ können Sie die Parameter auf der Kommandozeile zu
cl.exe
. Das wird schrecklich kompliziert in Eile, obwohl, wenn Sie nicht mit MSBuild oder irgendeine Art von make-Datei. In diesem Fall würden Sie ändern müssen, die Befehlszeile zu (mindestens):Diese beiden Optionen natürlich davon ausgegangen, dass Ihr Windows-SDK-Verzeichnis wurde Hinzugefügt, um den Pfad. Ich bin mir ziemlich sicher, dass der installer macht das automatisch für Sie, aber ich bin nicht positiv. Wenn es nicht klappt, oder man entfernt diese Dateien von Ihrem Pfad, Sie müssen verwenden Sie voll qualifizierte Pfade zu den
*.lib
Dateien auf der Kommandozeile.Lesen die Dokumentation für das compiler-Optionen möglich ist ein guter Ort, um zu starten. Oder noch besser, wenn Sie nicht vertraut sind mit Windows-Programmierung, mit einer Umgebung wie Visual Studio bringt alle diese Dinge zusammen, die für Sie automatisch. Wenn Sie verstehen, was vor sich geht, zu sehen, was die Befehlszeile von Visual Studio ausgeführt wird, und sezieren bit-by-bit.
Nächste problem ist, dass man kompilieren ohne Unicode definiert, und da ANSI ist die Standard -, alle Makros in der Windows-header-Dateien sind die Lösung zu nennen, die
A
nachgestellten Versionen der SDK-Funktionen. Dies ist wahrscheinlich nicht das, was Sie wollen. Windows wurde vollständig Unicode-jetzt für über ein Jahrzehnt, und alle neuen Anwendungen sollte gebaut werden als Unicode. Die Unicode-Versionen haben eineW
suffix angehängt an Ihren Namen.Wieder, können Sie den compiler anweisen zu bauen mit Unicode explizit entweder durch hinzufügen von Linien, um Ihre Quell-Datei, oder hinzufügen von Parametern an die Befehlszeile.
In diesem Fall, die einfachste Möglichkeit ist wohl nur hinzuzufügen
an die Spitze der Quellcode-Datei vor
#include <windows.h>
. Gerade wie wir oben sahen, aus der Visual Studio-UmgebungUNICODE
wird automatisch für Sie definiert, wenn Sie explizit ändern Sie die Projekteinstellungen, um den Gegner etwas anderes.WinMain
wenn ich#define UNICODE
? Ich Las etwas darüber, dass der compiler sich nicht beschweren, wenn ich geradeWinMain
._tWinMain
im Sinne<tchar.h>
.WinMain
ist der name der ANSI-Funktion;wWinMain
ist der name der Unicode-Funktion. Sie sind die gleichen, so lange, wie Sie erklären, dielpCmdLine
parameter als TypLPTSTR
(Saiten sind die einzigen Dinge, die ändern sich von ANSI zu Unicode, und durch die Verwendung dieser makro, der korrekte string-Typ wird automatisch ermittelt zur compile-Zeit), das ist der Grund, warum der compiler nicht meckern. Sorry, das ist verwirrend; Windows-Programmierung auf dem niedrigen Niveau bedeutet, muss man sich mit den Jahren der rückwärts-Kompatibilität.