这个 MSVC++ 编译错误是什么意思 [英] What does this MSVC++ compile error mean

查看:23
本文介绍了这个 MSVC++ 编译错误是什么意思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个编译错误,我不明白出了什么问题.我的 Microsoft Visual Studio 项目是一个 Win32 项目(不是控制台):

I have this compile error that I dont understand what is wrong. My Microsoft Visual Studio project is a Win32 Project (not console):

1>MSVCRT.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
1>C:\Users\Soribo\Desktop\C++ Programming\Visual C++ Programming\KeyboardHook\Release\KeyboardHook.exe : fatal error LNK1120: 1 unresolved externals

将#include "stdafx.h" 作为第一行后,编译错误是:

1>MSVCRT.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
1>C:\Users\Soribo\Desktop\C++ Programming\Visual C++ Programming\KeyboardHook\Release\KeyboardHook.exe : fatal error LNK1120: 1 unresolved externals

嗯,我已经定义了 WinMain 函数,不是吗?见下面的代码:

/*
  Application: 
*/

#include <windows.h>
#include <cstdlib>
#include "stdafx.h"

using namespace std;

static HHOOK     keyboardHook;
static HINSTANCE gInstance;


// Functions List //
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam );
HHook ActivateKeyboardHook( HookProc hookProc, HINSTANCE hInstance );
bool DeactivateKeyboardHook( HHook keyboardHook );


int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
//int WINAPI WinMain( HINSTANCE gInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = gInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(DKGRAY_BRUSH);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = L"Custom Class";
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    // if registration of main class fails
    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window Registration Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        L"Custom Class",
        L"App Name",
        WS_CAPTION|WS_MINIMIZEBOX|WS_VISIBLE|WS_OVERLAPPED|WS_SYSMENU,
        CW_USEDEFAULT, CW_USEDEFAULT, 600, 500,
        NULL, NULL, gInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, L"Window Creation Failed!", L"Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
    /*if ( code < 0 )
    {
        return CallNextHookEx( NULL, code, wParam, lParam );
    }*/  

    switch ( wParam )
    {
        case WM_KEYDOWN:
        {
            MessageBox( NULL, L"Notify", L"Key Down", MB_OK );        
        }
        break;
        case WM_KEYUP:
        {
            MessageBox( NULL, L"Notify", L"Key Up", MB_OK );                        
        }
        break;
        case WM_SYSKEYDOWN:
        {
            MessageBox( NULL, L"Notify", L"Sys Key Down", MB_OK );                        
        }
        break;
        case WM_SYSKEYUP:
        {
            MessageBox( NULL, L"Notify", L"Sys Key Up", MB_OK );                        
        }
        break;
        default:
        {
        } 
        break;
    }

    return CallNextHookEx( NULL, nCode, wParam, lParam );
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch(msg)
    {
        case WM_CREATE:
        {                  
             keyboardHook = ActivateKeyboardHook( &LowLevelKeyboardProc, gInstance );
        }    
        break;
        case WM_COMMAND:
        {
             switch(LOWORD(wParam)) 
             {

                  default:
                  break;
             }
        }
        break;
        case WM_CLOSE:
        {
            DeactivateKeyboardHook( keyboardHook );
            DestroyWindow(hwnd);
        }
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default: 
        break;
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

HHOOK ActivateKeyboardHook( HookProc hookProc, HINSTANCE hInstance )
{
     return SetWindowsHookEx( WH_KEYBOARD_LL, hookProc, hInstance, 0 );
}

bool DeactivateKeyboardHook( HHook keyboardHook )
{
     return UnhookWindowsHookEx( keyboardHook );
}

推荐答案

那不是编译错误,是链接器错误,说明你的程序没有定义WinMain函数,这是入口程序的要点.

That is not compilation error, that is linker error, and it means your program doesn't define WinMain function, which is entry point of the program.

确保你的程序有这个功能:

Make sure your program has this function:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);

请参阅此 MSDN 文档:

See this MSDN documentation:

#include <windows.h>
#include <cstdlib>
#include "stdafx.h"

如果你选择了预编译头文件,那么上面是错误的,stdafx.h 应该包含在文件的开头.因此将顺序更改为:

If you've chosen precompiled header file, then the above is wrong, stdafx.h should be included at the beginning of the file. So change the order as:

#include "stdafx.h"  //this should be first line of the program!
#include <windows.h>
#include <cstdlib>

而且我认为您不需要包含 因为很可能 stdafx.h 已经包含它了.看看吧.

And I think you don't need to include <windows.h> as most likely stdafx.h have included it already. Check it out.

现在为什么要先包含它?因为预编译头,顾名思义,是一个预编译头.编译器不会每次都编译它.相反,它一次编译其中的所有内容.如果你不先包含它,编译器将不知道是否编译它之前包含的文件,因为这些文件可能已经包含在 stdafx.h 中,所以已经编译好了.请参阅此主题:

Now why should it be included first? Because precompiled header, as the name suggests, is a precompiled header. The compiler doesn't compile it everytime. Instead, it compiles all the content in it once. If you don't include it first, the compiler will not know that whether to compile the files included before it or not, because it may be that those files are already included in stdafx.h and so has already be compiled. See this topic:

  • include stdafx.h in header or source file? (at stackoverflow)
  • Use Precompiled Header File (at MSDN)

这篇关于这个 MSVC++ 编译错误是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆