Что означает эта ошибка компиляции MSVC ++ - PullRequest
4 голосов
/ 12 июня 2011

У меня ошибка компиляции, я не понимаю, что не так.Мой проект Microsoft Visual Studio - это проект Win32 (не консольный):

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

Ответы [ 2 ]

6 голосов
/ 12 июня 2011

Это не ошибка компиляции, это ошибка компоновщика, и это означает, что ваша программа не определяет функцию WinMain, которая является точкой входа в программу.

Убедитесь, что ваша программа имеет эту функцию:

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

См. Эту документацию MSDN:


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

Если вы выбрали предварительно скомпилированный заголовочный файл, то вышеприведенное неверно, stdafx.h следует включить в начало файла. Поэтому измените порядок следующим образом:

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

И я думаю, вам не нужно включать <windows.h>, поскольку, скорее всего, stdafx.h уже включили его. Проверьте это.

Теперь, почему это должно быть включено сначала? Поскольку предварительно скомпилированный заголовок, как следует из названия, является предварительно скомпилированным заголовком. Компилятор не компилирует его каждый раз. Вместо этого он компилирует весь контент в нем один раз. Если вы не включите его в первую очередь, компилятор не будет знать, нужно ли скомпилировать файлы, включенные до него, или нет, потому что может быть, что эти файлы уже включены в stdafx.h и поэтому уже скомпилированы. Смотрите эту тему:

0 голосов
/ 12 июня 2011

Это не ошибка компиляции, это ошибка ссылки.По сути, вы используете функцию, которую вы где-то объявили, но никогда не определяли ни в одной единице перевода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...