error LNK2019: unresolved external symbol _main referenced infunction ___tmainCRTStartup MSVCRTD.lib

Discussion in 'C++' started by Tauqir, Apr 5, 2010.

  1. Tauqir

    Tauqir Guest

    Hi,
    I am trying a very simple windows tutorial, all code is from the
    tutorial but at compile time it is giving the above error. I am using
    Visual Studio 2008 C++, starting with an empty project, Here is the
    code:
    Any ideas, where is this function _tmainCETStartup coming in from and
    where should be what it is looking for?

    #include <windows.h>

    LPCTSTR ClsName = L"BasicApp";
    LPCTSTR WndName = L"A Simple Window";

    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT uMsg,
    WPARAM wParam, LPARAM lParam);

    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
    {
    MSG Msg;
    HWND hWnd;
    WNDCLASSEX WndClsEx;

    // Create the application window
    WndClsEx.cbSize = sizeof(WNDCLASSEX);
    WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
    WndClsEx.lpfnWndProc = WndProcedure;
    WndClsEx.cbClsExtra = 0;
    WndClsEx.cbWndExtra = 0;
    WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClsEx.lpszMenuName = NULL;
    WndClsEx.lpszClassName = ClsName;
    WndClsEx.hInstance = hInstance;
    WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    // Register the application
    RegisterClassEx(&WndClsEx);

    // Create the window object
    hWnd = CreateWindow(ClsName,
    WndName,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    NULL,
    NULL,
    hInstance,
    NULL);

    // Find out if the window was created
    if( !hWnd ) // If the window was not created,
    return 0; // stop the application

    // Display the window to the user
    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    // Decode and treat the messages
    // as long as the application is running
    while( GetMessage(&Msg, NULL, 0, 0) )
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }

    return Msg.wParam;
    }

    LRESULT CALLBACK WndProcedure(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
    {
    switch(Msg)
    {
    // If the user wants to close the application
    case WM_DESTROY:
    // then close it
    PostQuitMessage(WM_QUIT);
    break;
    default:
    // Process the left-over messages
    return DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    // If something was not done, let it go
    return 0;
    }
     
    Tauqir, Apr 5, 2010
    #1
    1. Advertising

  2. * Leigh Johnston:
    > * Leigh Johnston:
    >> * Tauqir:
    >>>
    >>> I am trying a very simple windows tutorial, all code is from the
    >>> tutorial but at compile time it is giving the above error. I am using
    >>> Visual Studio 2008 C++, starting with an empty project, Here is the
    >>> code:
    >>> Any ideas, where is this function _tmainCETStartup coming in from and
    >>> where should be what it is looking for?

    [snip code]
    >>
    >> Try creating the project again but this time choose "Win32 Project /
    >> Windows Application" and not "Win32 Console Application / Console
    >> Application".

    >
    > After doing that ensure you use the following for "WinMain":
    >
    > int APIENTRY _tWinMain(HINSTANCE hInstance,
    > HINSTANCE hPrevInstance,
    > LPTSTR lpCmdLine,
    > int nCmdShow)
    > {
    > }
    >
    > Especially important is the LPTSTR to avoid Unicode/ANSI problems
    > although the linker might be forgiving.


    Tauqir: evidently you mistyped the name of the missing function. I presume it
    was 'mainCRTStartup'.

    'mainCRTStartup' is one of several Microsoft runtime library functions that can
    be used as your program's entry point, where the execution starts. This
    particular function calls a standard C or C++ 'main' function, which you are
    supposed to define. The others call other non-standard startup functions such as
    WinMain.

    With Microsoft's toolchain one way to specify which entry point function to use
    is to choose the right project type in Visual Studio, as Leigh advised.
    Ultimately that translates down to an /entry option being passed to the linker,
    or no such option (for the default). The determination of a default is intricate
    and as far as I know not documented, so to take charge, when you want to do
    that, you need to use /entry (it can be specified in the project settings).

    Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like "we
    all know that" among many Windows programmers. However, it's advice that once
    (early to middle 90's) was great, but which after that is wrong, perpetuated by
    bad Microsoft code examples and copycat programming & teaching. It's like advice
    talking about proper care of horses in order to help you drive safely to work.

    First, the OP's code uses plain Unicode string like L"ouch", which means the
    source will only compile with one setting of T-stuff, namely Unicode.

    Secondly, supporting Windows 9x, which the T-stuff is about, is as of 2010 not
    worth the effort.

    Third, except when using MFC the way to go for supporting Unicode in Windows 9x
    (if some evil manager requires that) is to use Microsoft's Layer for Unicode.

    In short, T-stuff is just silly and adds a lot of needless work, and if one
    absolutely feels that one must use a Microsoft specific startup function instead
    of standard 'main', then that should be 'wMain' or 'wWinMain' (Unicode).

    Here's the OP's code reworked to less Microsoft'isms, less C'isms, and without
    the extremely misleading & incorrect comments:

    <code>
    #define STRICT
    #define UNICODE
    #include <windows.h>
    #include <stdexcept>

    bool throwX( char const s[] ) { throw std::runtime_error( s ); }

    wchar_t const windowClassName[] = L"BasicApp";
    wchar_t const windowTitle[] = L"A Simple Window";

    LRESULT CALLBACK windowProcedure(
    HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
    )
    {
    switch( msg_id )
    {
    case WM_DESTROY: // Window is being destroyed.
    PostQuitMessage( WM_QUIT ); // Terminates message loop.
    break;
    default:
    return DefWindowProc( windowHandle, msg_id, wParam, lParam );
    }
    return 0;
    }

    void registerWindowClass()
    {
    WNDCLASSEX info = { sizeof( WNDCLASSEX ) };

    info.style = CS_HREDRAW | CS_VREDRAW;
    info.lpfnWndProc = windowProcedure;
    info.hIcon = LoadIcon( 0, IDI_APPLICATION );
    info.hCursor = LoadCursor( 0, IDC_ARROW );
    info.hbrBackground = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );
    info.lpszClassName = windowClassName;
    info.hInstance = GetModuleHandle( 0 );
    info.hIconSm = LoadIcon( 0, IDI_APPLICATION );
    RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" );
    }

    HWND createMainWindow()
    {
    HWND const handle = CreateWindow(
    windowClassName,
    windowTitle,
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    0,
    0,
    GetModuleHandle( 0 ),
    0
    );
    handle != 0 || throwX( "CreateWindow failed" );
    return handle;
    }

    void processMessages()
    {
    MSG msg;
    while( GetMessage( &msg, 0, 0, 0 ) > 0 )
    {
    TranslateMessage( &msg );
    DispatchMessage( &msg );
    }
    }

    void cppMain()
    {
    registerWindowClass();
    ShowWindow( createMainWindow(), SW_SHOWNORMAL );
    processMessages();
    }

    int main()
    {
    try
    {
    cppMain();
    return EXIT_SUCCESS;
    }
    catch( std::exception const& )
    {
    return EXIT_FAILURE;
    }
    }
    </code>

    Note to OP: the GNU toolchain's linker is happy with the standard 'main' also
    for a GUI subsystem application, but Microsoft's tools are geared towards more
    non-standard behavior, so for a GUI subsystem app, in the project properties you
    may have to specify '/entry:mainCRTStartup' (linker option).



    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Apr 5, 2010
    #2
    1. Advertising

  3. Tauqir

    Tauqir Guest

    On Apr 4, 7:12 pm, "Alf P. Steinbach" <> wrote:
    > * Leigh Johnston:
    >
    >
    >
    >
    >
    > > * Leigh Johnston:
    > >> * Tauqir:

    >
    > >>> I am trying a very simple windows tutorial, all code is from the
    > >>> tutorial but at compile time it is giving the above error. I am using
    > >>> Visual Studio 2008 C++, starting with an empty project, Here is the
    > >>> code:
    > >>> Any ideas, where is this function _tmainCETStartup coming in from and
    > >>> where should be what it is looking for?

    > [snip code]
    >
    > >> Try creating the project again but this time choose "Win32 Project /
    > >> Windows Application" and not "Win32 Console Application / Console
    > >> Application".

    >
    > > After doing that ensure you use the following for "WinMain":

    >
    > > int APIENTRY _tWinMain(HINSTANCE hInstance,
    > >                     HINSTANCE hPrevInstance,
    > >                     LPTSTR    lpCmdLine,
    > >                     int       nCmdShow)
    > > {
    > > }

    >
    > > Especially important is the LPTSTR to avoid Unicode/ANSI problems
    > > although the linker might be forgiving.

    >
    > Tauqir: evidently you mistyped the name of the missing function. I presume it
    > was 'mainCRTStartup'.
    >
    > 'mainCRTStartup' is one of several Microsoft runtime library functions that can
    > be used as your program's entry point, where the execution starts. This
    > particular function calls a standard C or C++ 'main' function, which you are
    > supposed to define. The others call other non-standard startup functions such as
    > WinMain.
    >
    > With Microsoft's toolchain one way to specify which entry point function to use
    > is to choose the right project type in Visual Studio, as Leigh advised.
    > Ultimately that translates down to an /entry option being passed to the linker,
    > or no such option (for the default). The determination of a default is intricate
    > and as far as I know not documented, so to take charge, when you want to do
    > that, you need to use /entry (it can be specified in the project settings).
    >
    > Leigh: I'm certain your advise about LPTSTR is well-meant, and it is like "we
    > all know that" among many Windows programmers. However, it's advice that once
    > (early to middle 90's) was great, but which after that is wrong, perpetuated by
    > bad Microsoft code examples and copycat programming & teaching. It's like advice
    > talking about proper care of horses in order to help you drive safely to work.
    >
    > First, the OP's code uses plain Unicode string like L"ouch", which means the
    > source will only compile with one setting of T-stuff, namely Unicode.
    >
    > Secondly, supporting Windows 9x, which the T-stuff is about, is as of 2010 not
    > worth the effort.
    >
    > Third, except when using MFC the way to go for supporting Unicode in Windows 9x
    > (if some evil manager requires that) is to use Microsoft's Layer for Unicode.
    >
    > In short, T-stuff is just silly and adds a lot of needless work, and if one
    > absolutely feels that one must use a Microsoft specific startup function instead
    > of standard 'main', then that should be 'wMain' or 'wWinMain' (Unicode).
    >
    > Here's the OP's code reworked to less Microsoft'isms, less C'isms, and without
    > the extremely misleading & incorrect comments:
    >
    > <code>
    > #define     STRICT
    > #define     UNICODE
    > #include <windows.h>
    > #include <stdexcept>
    >
    > bool throwX( char const s[] ) { throw std::runtime_error( s ); }
    >
    > wchar_t const windowClassName[] = L"BasicApp";
    > wchar_t const windowTitle[]     = L"A Simple Window";
    >
    > LRESULT CALLBACK windowProcedure(
    >      HWND windowHandle, UINT msg_id, WPARAM wParam, LPARAM lParam
    >      )
    > {
    >      switch( msg_id )
    >      {
    >      case WM_DESTROY:                    // Window is being destroyed.
    >          PostQuitMessage( WM_QUIT );     // Terminates message loop.
    >          break;
    >      default:
    >          return DefWindowProc( windowHandle, msg_id, wParam, lParam );
    >      }
    >      return 0;
    >
    > }
    >
    > void registerWindowClass()
    > {
    >      WNDCLASSEX  info    = { sizeof( WNDCLASSEX ) };
    >
    >      info.style          = CS_HREDRAW | CS_VREDRAW;
    >      info.lpfnWndProc    = windowProcedure;
    >      info.hIcon          = LoadIcon( 0, IDI_APPLICATION );
    >      info.hCursor        = LoadCursor( 0, IDC_ARROW );
    >      info.hbrBackground  = reinterpret_cast<HBRUSH>( COLOR_WINDOW + 1 );
    >      info.lpszClassName  = windowClassName;
    >      info.hInstance      = GetModuleHandle( 0 );
    >      info.hIconSm        = LoadIcon( 0, IDI_APPLICATION );
    >      RegisterClassEx( &info ) || throwX( "RegisterClassEx failed" );
    >
    > }
    >
    > HWND createMainWindow()
    > {
    >      HWND const handle = CreateWindow(
    >          windowClassName,
    >          windowTitle,
    >          WS_OVERLAPPEDWINDOW,
    >          CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
    >          0,
    >          0,
    >          GetModuleHandle( 0 ),
    >          0
    >          );
    >      handle != 0 || throwX( "CreateWindow failed" );
    >      return handle;
    >
    > }
    >
    > void processMessages()
    > {
    >      MSG msg;
    >      while( GetMessage( &msg, 0, 0, 0 ) > 0 )
    >      {
    >          TranslateMessage( &msg );
    >          DispatchMessage( &msg );
    >      }
    >
    > }
    >
    > void cppMain()
    > {
    >      registerWindowClass();
    >      ShowWindow( createMainWindow(), SW_SHOWNORMAL );
    >      processMessages();
    >
    > }
    >
    > int main()
    > {
    >      try
    >      {
    >          cppMain();
    >          return EXIT_SUCCESS;
    >      }
    >      catch( std::exception const& )
    >      {
    >          return EXIT_FAILURE;
    >      }}
    >
    > </code>
    >
    > Note to OP: the GNU toolchain's linker is happy with the standard 'main' also
    > for a GUI subsystem application, but Microsoft's tools are geared towards more
    > non-standard behavior, so for a GUI subsystem app, in the project properties you
    > may have to specify '/entry:mainCRTStartup' (linker option).
    >
    > Cheers & hth.,
    >
    > - Alf- Hide quoted text -
    >
    > - Show quoted text -


    Guys, Thanks very much,
    I started with the Win32Project / Windows application and of course
    the startup project does give me a working starting point with
    _tWinMain as the windows APIENTRY point.
    Interestingly Unicode is at the core of my work. Purpose is to make a
    simplest unicode editor for my native language,'Urdu'. A lot of people
    type Urdu in English script and I just cannot stand it.
    I initailly started with C Sharp, but was unable to get the client
    area where users encoded strings will be displayed. Only option was to
    use the Rich Text control, but that was rather limiting, because it
    had to be on a form.
    Now my challenge is to read user input (c=getchar()? )- based on a
    keyboard mapping - encode the character in Urdu and display
    (putchar(c) )it in the Arial Unicode MS, which is shipped with Windows
    XP. No Windows 98 consideration.
    My C++ skills are at this moment rusted. A few lines of code to get
    this done will be a great boost at this time.

    Tauqir
     
    Tauqir, Apr 9, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Scott Allen
    Replies:
    8
    Views:
    10,982
    Scott Allen
    May 2, 2004
  2. Mastadex
    Replies:
    4
    Views:
    743
    Mastadex
    Oct 1, 2005
  3. NewsGroup
    Replies:
    3
    Views:
    678
    Michael
    Oct 27, 2006
  4. Trent
    Replies:
    9
    Views:
    629
    Trent
    Jun 29, 2007
  5. Replies:
    1
    Views:
    328
Loading...

Share This Page