2016-06-01 2 views
1

学習の練習として、明示的にWindows.hを含めずにウィンドウを登録して作成する標準のWindowsプログラムを作成しました。 Windows.hのすべてのヘッダーシンボルが抽出され、ソースに含めるカスタムヘッダーに配置されます。カスタムヘッダーには、CreateWindowWNDCLASSEXのような型定義があります。WindowsHなしのWIN32でコンパイル

プログラムは、そのようなコマンドラインでcl.exeしてコンパイルされています

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

これらの.libファイルが関連付けられているから、関数のアドレスにロードするためのセットアップ作業を行う輸入libsにあるというのが私の理解ですプロセスの起動時にDLL。 main.cppWindows.hが直接含まれている場合、上記のコマンドラインは完全に正常に動作します。ただし、カスタムヘッダーを含めると、コマンドラインで関連付けられたインポートライブラリを指定したにもかかわらず、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% 
+1

[最小限で完全であり、検証可能な例](http://stackoverflow.com/help/mcve)を投稿してください。 – MikeCAT

+0

@MikeCATよろしいですか!しばらくお待ちください。 – Cecil

+1

@RandyGaul ** minimal **を念頭に置いてください。 –

答えて

4

いいえ、ツールは特にWINDOWS.Hために何もしません。

あなたのヘッダーが間違っていると思います。ヘッダーを見ることなく問題が何かを推測するのは難しいですが、一つの可能​​性が出てきます。

ほとんどの関数では、Windowsには「ANSI」と「Wide」の両方のバージョンがあるため、CreateWindowと表示されるのは実際には2つの関数CreateWindowACreateWindowWです。 CreateWindowは、UNICODEが定義されているかどうかに応じて、または*Wのいずれかの名前にマップされるマクロとしてのみ存在します。

あなたはCreateWindowという名前の関数のプロトタイプ/宣言を提供してきましたのであれば、リンクするつもりはない - CreateWindow、どのライブラリに存在するCreateWindowACreateWindowWありません。

+0

プロトタイプで適切な呼び出し規約修飾子を指定して、それらを 'extern C'セクションに置くように注意してください。 –

+0

申し訳ありませんが、私は例を追加しました! @MarkRansom実際に私は 'extern C'セクションをまだ追加しようとしていません。私は間違いなくそれが必要です... – Cecil

+0

@MarkRansomうん、それはまさに問題だった。私は 'extern C'を忘れてしまいました。 – Cecil

関連する問題