Als Lernübung habe ich ein Standard-Windows-Programm geschrieben, das ein Fenster registriert und erstellt, ohne explizit Windows.h
einzuschließen. Alle Header-Symbole von Windows.h
wurden extrahiert und in einen benutzerdefinierten Header platziert, den ich in die Quelle einfüge. Der benutzerdefinierte Header verfügt über Typdefinitionen wie CreateWindow
und WNDCLASSEX
.Kompilieren auf WIN32 ohne Windows.h
Das Programm ist wie so mit cl.exe
mit einer Befehlszeile kompiliert:
cl main.cpp /link opengl32.lib gdi32.lib kernel32.lib user32.lib
Es ist mein Verständnis, dass diese LIB-Dateien importieren Libs sind, die von dem zugehörigen in Funktionsadressen zum Laden von Setup-Arbeit zu tun DLLs beim Start des Prozesses. Die obige Befehlszeile funktioniert einwandfrei, wenn main.cpp
direkt Windows.h
enthält. Wenn Sie jedoch den benutzerdefinierten Header cl.exe
einfügen, können alle Funktionsaufrufe, die in der Windows-API vorgenommen wurden, nicht verknüpft werden, obwohl die zugehörigen Import-Bibliotheken in der Befehlszeile angegeben wurden (ungelöste externe Symbolfehler).
Gibt es eine Art Sonderfall Magie cl.exe
führt speziell für Windows.h
? Welche Schritte sind erforderlich, um in diesem Szenario eine ordnungsgemäße Verknüpfung sicherzustellen?
Hier ist das kleinste Beispiel, das ich bauen konnte:
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
typedef __int64 LONG_PTR, *PLONG_PTR;
typedef UINT_PTR WPARAM;
typedef LONG_PTR LPARAM;
typedef LONG_PTR LRESULT;
typedef int INT;
typedef unsigned int UINT;
typedef char CHAR;
typedef unsigned short WORD;
#define CONST const
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
DECLARE_HANDLE(HWND);
DECLARE_HANDLE(HINSTANCE);
DECLARE_HANDLE(HICON);
DECLARE_HANDLE(HCURSOR);
DECLARE_HANDLE(HBRUSH);
DECLARE_HANDLE(HMODULE);
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
typedef CHAR *NPSTR, *LPSTR, *PSTR;
typedef CONST CHAR *LPCSTR, *PCSTR;
#define CALLBACK __stdcall
#define WINAPI __stdcall
typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
#define DECLSPEC_IMPORT __declspec(dllimport)
#define WINUSERAPI DECLSPEC_IMPORT
#define WINBASEAPI DECLSPEC_IMPORT
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_OWNDC 0x0020
#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
#define MAKEINTRESOURCE MAKEINTRESOURCEA
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define NULL 0
typedef WORD ATOM; //BUGBUG - might want to remove this from minwin
typedef struct tagWNDCLASSEXA {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXA, *PWNDCLASSEXA, *NPWNDCLASSEXA, *LPWNDCLASSEXA;
WINUSERAPI LRESULT CALLBACK DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
WINBASEAPI HMODULE WINAPI GetModuleHandleA(LPCSTR lpModuleName);
WINUSERAPI HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR lpCursorName);
WINUSERAPI ATOM WINAPI RegisterClassExA(CONST WNDCLASSEXA *);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return DefWindowProcA(hWnd, message, wParam, lParam);
}
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, INT sw)
{
// register window class
WNDCLASSEXA wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEXA);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = (HINSTANCE)GetModuleHandleA(NULL);
wcex.hIcon = NULL;
wcex.hCursor = LoadCursorA(NULL, IDC_ARROW);
wcex.lpszClassName = "Title";
RegisterClassExA(&wcex);
return 0;
}
Zusammengestellt mit:
@echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
set CONSOLE= -subsystem:windows
set CFLAGS= -Zi -nologo
set CFLAGS= -D__WINDOWS__ -D_CRT_SECURE_NO_WARNINGS %CFLAGS%
set LFLAGS= -incremental:no -opt:ref
set LFLAGS= user32.lib kernel32.lib %LFLAGS%
cl %CFLAGS% main.cpp -Fegame.exe /link %LFLAGS% %CONSOLE%
Würde es Ihnen etwas ausmachen, ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) zu veröffentlichen. – MikeCAT
@MikeCAT Okay sicher! Gib mir bitte ein paar Minuten. – Cecil
@RandyGaul Behalte das ** minimal ** im Hinterkopf. –