gpt4 book ai didi

c++ - 在没有 Windows.h 的情况下在 WIN32 上编译

转载 作者:可可西里 更新时间:2023-11-01 11:16:45 24 4
gpt4 key购买 nike

作为学习练习,我编写了一个标准的 Windows 程序,该程序注册并创建了一个窗口,但没有显式包含 Windows.hWindows.h 中的所有 header 符号都已提取并放入我包含在源代码中的自定义 header 中。自定义 header 具有类型定义,例如 CreateWindowWNDCLASSEX

程序是用 cl.exe 编译的,命令行如下:

cl main.cpp/link opengl32.lib gdi32.lib kernel32.lib user32.lib

据我了解,这些 .lib 文件是导入库,它们在进程启动时执行设置工作以从关联的 DLL 加载函数地址。如果 main.cpp 直接包含 Windows.h,上述命令行将工作得很好。但是,当包含自定义 header 时,cl.exe 无法将所有函数调用链接到 Windows API 中,尽管在命令行上指定了关联的导入库(未解析的外部符号错误)。

cl.exe 是否专门为 Windows.h 执行某种特例魔术?在这种情况下需要采取哪些步骤来确保正确链接?

这是我能构造的最小示例:

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;
}

编译:

@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%

最佳答案

不,这些工具对 windows.h 没有任何作用。

我猜你把标题弄错了。如果没有看到标题,很难猜测问题可能是什么,但有一种可能性很明显。

对于大多数函数,Windows 都有“ANSI”和“Wide”版本,所以您看到的 CreateWindow 实际上是两个函数 CreateWindowACreateWindowWCreateWindow 仅作为映射到 *A*W 名称的宏存在,具体取决于 UNICODE已定义。

因此,如果您为名为 CreateWindow 的函数提供了原型(prototype)/声明,它不会链接——库中存在的是 CreateWindowACreateWindowW,不是 CreateWindow

关于c++ - 在没有 Windows.h 的情况下在 WIN32 上编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37574117/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com