Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Getting application startup to call main()

Getting application startup to call main()

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Perdrix
    wrote on 1 May 2023, 09:09 last edited by Perdrix 5 Jan 2023, 09:23
    #1

    I'm converting an application from MFC to Qt.

    I just replaced

    int WINAPI _tWinMain(
    	[[maybe_unused]] HINSTANCE hInstance,  // handle to current instance
    	[[maybe_unused]] HINSTANCE hPrevInstance,  // handle to previous instance
    	[[maybe_unused]] LPTSTR lpCmdLine,      // pointer to command line
    	[[maybe_unused]] int nCmdShow          // show state of window
    				   )
    

    in the main startup cpp file with a regular:

    int main(int argc, char* argv[])
    

    But when I try to run it the code throws an exception in Microsoft's winmain.cpp function AfxWinMain()

    Which means it's not picking up something I need to divert the call to my "old style" main().

    Probably something in one of the Qt libraries ( the qtentrypoint_win stuff)?

    Qt Modules is set to core;gui;gui-private;widgets;network

    What did I fail to do ?

    Thanks, David

    J C 2 Replies Last reply 1 May 2023, 09:38
    0
    • P Perdrix
      1 May 2023, 09:09

      I'm converting an application from MFC to Qt.

      I just replaced

      int WINAPI _tWinMain(
      	[[maybe_unused]] HINSTANCE hInstance,  // handle to current instance
      	[[maybe_unused]] HINSTANCE hPrevInstance,  // handle to previous instance
      	[[maybe_unused]] LPTSTR lpCmdLine,      // pointer to command line
      	[[maybe_unused]] int nCmdShow          // show state of window
      				   )
      

      in the main startup cpp file with a regular:

      int main(int argc, char* argv[])
      

      But when I try to run it the code throws an exception in Microsoft's winmain.cpp function AfxWinMain()

      Which means it's not picking up something I need to divert the call to my "old style" main().

      Probably something in one of the Qt libraries ( the qtentrypoint_win stuff)?

      Qt Modules is set to core;gui;gui-private;widgets;network

      What did I fail to do ?

      Thanks, David

      J Offline
      J Offline
      JonB
      wrote on 1 May 2023, 09:38 last edited by JonB 5 Jan 2023, 09:42
      #2

      @Perdrix
      Well, yes, it would, because an MFC program calls AfxWinMain() and that requires int WINAPI _tWinMain(). You need to remove the MFC stuff (completely, and stop linking against MFC libraries) before this issue will go away.

      J 1 Reply Last reply 1 May 2023, 12:48
      2
      • P Perdrix
        1 May 2023, 09:09

        I'm converting an application from MFC to Qt.

        I just replaced

        int WINAPI _tWinMain(
        	[[maybe_unused]] HINSTANCE hInstance,  // handle to current instance
        	[[maybe_unused]] HINSTANCE hPrevInstance,  // handle to previous instance
        	[[maybe_unused]] LPTSTR lpCmdLine,      // pointer to command line
        	[[maybe_unused]] int nCmdShow          // show state of window
        				   )
        

        in the main startup cpp file with a regular:

        int main(int argc, char* argv[])
        

        But when I try to run it the code throws an exception in Microsoft's winmain.cpp function AfxWinMain()

        Which means it's not picking up something I need to divert the call to my "old style" main().

        Probably something in one of the Qt libraries ( the qtentrypoint_win stuff)?

        Qt Modules is set to core;gui;gui-private;widgets;network

        What did I fail to do ?

        Thanks, David

        C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 1 May 2023, 09:58 last edited by Chris Kawa 5 Jan 2023, 10:03
        #3

        @Perdrix Windows apps can be compiled as console or windows subsystem.
        When compiled as console app the default entry point is the classic main function. When compiled as windows subsystem the default entry point is either WinMain or wWinMain, depending on whether you compile as UNICODE or not. _tWinMain is just a define that translates to either of those two.

        MFC provides an implementation of _tWinMain in its appmodule.cpp. It calls AfxWinMain to initialize MFC app instance. So long as you're linking to MFC libraries it will be included in your app.

        Qt provides an implementation of both WinMain and wWinMain that simply calls the classic main, so that it works the same for console and windows subsystems. In Qt6 this is provided via Qt6EntryPoint lib that you have to link to.

        But since both frameworks provide WinMain you can't use that as long as you link to both, because you'll have multiple conflicting definitions.

        As a workaround for the time you're porting you can manually specify the entry point in the linker settings. Go to project properties -> Linker -> Advanced -> Entry Point and type mainCRTStartup in there. This will cause the app to use the classic main as a startup point and ignore the WinMain provided by MFC.
        When you're done porting remove that override, remove linking to MFC and link to Qt6EntryPoint.

        Btw. don't modify the winmain.cpp or appmodul.cpp files. Those are internal MFC files that should not be touched.

        P 1 Reply Last reply 1 May 2023, 12:23
        2
        • C Chris Kawa
          1 May 2023, 09:58

          @Perdrix Windows apps can be compiled as console or windows subsystem.
          When compiled as console app the default entry point is the classic main function. When compiled as windows subsystem the default entry point is either WinMain or wWinMain, depending on whether you compile as UNICODE or not. _tWinMain is just a define that translates to either of those two.

          MFC provides an implementation of _tWinMain in its appmodule.cpp. It calls AfxWinMain to initialize MFC app instance. So long as you're linking to MFC libraries it will be included in your app.

          Qt provides an implementation of both WinMain and wWinMain that simply calls the classic main, so that it works the same for console and windows subsystems. In Qt6 this is provided via Qt6EntryPoint lib that you have to link to.

          But since both frameworks provide WinMain you can't use that as long as you link to both, because you'll have multiple conflicting definitions.

          As a workaround for the time you're porting you can manually specify the entry point in the linker settings. Go to project properties -> Linker -> Advanced -> Entry Point and type mainCRTStartup in there. This will cause the app to use the classic main as a startup point and ignore the WinMain provided by MFC.
          When you're done porting remove that override, remove linking to MFC and link to Qt6EntryPoint.

          Btw. don't modify the winmain.cpp or appmodul.cpp files. Those are internal MFC files that should not be touched.

          P Offline
          P Offline
          Perdrix
          wrote on 1 May 2023, 12:23 last edited by Perdrix 5 Jan 2023, 12:28
          #4

          @Chris-Kawa Well here's the strange thing. One of my projects which I converted a long time back has a startup call stack that looks like this:

          DeepSkyStacker.exe!main(int argc, char * * argv) Line 904
          	at C:\Users\amonra\Documents\GitHub\DSS\DeepSkyStacker\DeepSkyStacker.cpp(904)
          DeepSkyStacker.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 50
          	at C:\Users\qt\work\qt\qtbase\src\entrypoint\qtentrypoint_win.cpp(50)
          DeepSkyStacker.exe!invoke_main() Line 107
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(107)
          DeepSkyStacker.exe!__scrt_common_main_seh() Line 288
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
          DeepSkyStacker.exe!__scrt_common_main() Line 331
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331)
          DeepSkyStacker.exe!WinMainCRTStartup(void * __formal) Line 17
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_winmain.cpp(17)
          kernel32.dll!BaseThreadInitThunk()
          ntdll.dll!RtlUserThreadStart()
          

          The one I am currently trying to convert has call stack up to the point of failure that looks like:

          mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 37
          	at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\winmain.cpp(37)
          DeepSkyStackerLive.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 26
          	at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\appmodul.cpp(26)
          DeepSkyStackerLive.exe!invoke_main() Line 123
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(123)
          DeepSkyStackerLive.exe!__scrt_common_main_seh() Line 288
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
          DeepSkyStackerLive.exe!__scrt_common_main() Line 331
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331)
          DeepSkyStackerLive.exe!wWinMainCRTStartup(void * __formal) Line 17
          	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp(17)
          kernel32.dll!BaseThreadInitThunk()
          ntdll.dll!RtlUserThreadStart()
          

          So clearly I must have done something to get the first one working!

          Note that I didn't override the Entry Point in the 1st of these projects

          J 1 Reply Last reply 1 May 2023, 12:34
          0
          • P Perdrix
            1 May 2023, 12:23

            @Chris-Kawa Well here's the strange thing. One of my projects which I converted a long time back has a startup call stack that looks like this:

            DeepSkyStacker.exe!main(int argc, char * * argv) Line 904
            	at C:\Users\amonra\Documents\GitHub\DSS\DeepSkyStacker\DeepSkyStacker.cpp(904)
            DeepSkyStacker.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 50
            	at C:\Users\qt\work\qt\qtbase\src\entrypoint\qtentrypoint_win.cpp(50)
            DeepSkyStacker.exe!invoke_main() Line 107
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(107)
            DeepSkyStacker.exe!__scrt_common_main_seh() Line 288
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
            DeepSkyStacker.exe!__scrt_common_main() Line 331
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331)
            DeepSkyStacker.exe!WinMainCRTStartup(void * __formal) Line 17
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_winmain.cpp(17)
            kernel32.dll!BaseThreadInitThunk()
            ntdll.dll!RtlUserThreadStart()
            

            The one I am currently trying to convert has call stack up to the point of failure that looks like:

            mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 37
            	at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\winmain.cpp(37)
            DeepSkyStackerLive.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 26
            	at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\appmodul.cpp(26)
            DeepSkyStackerLive.exe!invoke_main() Line 123
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(123)
            DeepSkyStackerLive.exe!__scrt_common_main_seh() Line 288
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288)
            DeepSkyStackerLive.exe!__scrt_common_main() Line 331
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331)
            DeepSkyStackerLive.exe!wWinMainCRTStartup(void * __formal) Line 17
            	at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp(17)
            kernel32.dll!BaseThreadInitThunk()
            ntdll.dll!RtlUserThreadStart()
            

            So clearly I must have done something to get the first one working!

            Note that I didn't override the Entry Point in the 1st of these projects

            J Offline
            J Offline
            JonB
            wrote on 1 May 2023, 12:34 last edited by JonB 5 Jan 2023, 12:35
            #5

            @Perdrix
            The first one you already got as far as (from invoke_main()):

            at C:\Users\qt\work\qt\qtbase\src\entrypoint\qtentrypoint_win.cpp(50)

            The second one still has at same point:

            at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\appmodul.cpp(26)

            So the first one has been moved to Qt, the second one is still MFC.

            You don't need to "override entry points" once you (fully) move from MFC to Qt.

            P 1 Reply Last reply 1 May 2023, 12:43
            0
            • J JonB
              1 May 2023, 12:34

              @Perdrix
              The first one you already got as far as (from invoke_main()):

              at C:\Users\qt\work\qt\qtbase\src\entrypoint\qtentrypoint_win.cpp(50)

              The second one still has at same point:

              at D:\a\_work\1\s\src\vctools\VC7Libs\Ship\ATLMFC\Src\MFC\appmodul.cpp(26)

              So the first one has been moved to Qt, the second one is still MFC.

              You don't need to "override entry points" once you (fully) move from MFC to Qt.

              P Offline
              P Offline
              Perdrix
              wrote on 1 May 2023, 12:43 last edited by Perdrix 5 Jan 2023, 12:47
              #6

              @JonB That's the whole issue! I have no MFC GUI code left in that source tree, so I want to be fully moved over to Qt. There are a few Windows calls that notionally might qualify as MFC but...

              1 Reply Last reply
              0
              • J JonB
                1 May 2023, 09:38

                @Perdrix
                Well, yes, it would, because an MFC program calls AfxWinMain() and that requires int WINAPI _tWinMain(). You need to remove the MFC stuff (completely, and stop linking against MFC libraries) before this issue will go away.

                J Offline
                J Offline
                JonB
                wrote on 1 May 2023, 12:48 last edited by
                #7

                @Perdrix

                @JonB said in Getting application startup to call main():

                You need to remove the MFC stuff (completely, and stop linking against MFC libraries) before this issue will go away.

                Did you remove linking against MFC libraries? Because the traceback starts with mfc140ud.dll!AfxWinMain....

                P 1 Reply Last reply 1 May 2023, 12:51
                1
                • J JonB
                  1 May 2023, 12:48

                  @Perdrix

                  @JonB said in Getting application startup to call main():

                  You need to remove the MFC stuff (completely, and stop linking against MFC libraries) before this issue will go away.

                  Did you remove linking against MFC libraries? Because the traceback starts with mfc140ud.dll!AfxWinMain....

                  P Offline
                  P Offline
                  Perdrix
                  wrote on 1 May 2023, 12:51 last edited by
                  #8

                  @JonB I needed to define _AFXDLL

                  J 1 Reply Last reply 1 May 2023, 12:54
                  0
                  • P Perdrix
                    1 May 2023, 12:51

                    @JonB I needed to define _AFXDLL

                    J Offline
                    J Offline
                    JonB
                    wrote on 1 May 2023, 12:54 last edited by JonB 5 Jan 2023, 12:55
                    #9

                    @Perdrix
                    I cannot imagine why, you have a program which (according to you) has no vestiges of MFC left and has nothing to do with MFC. Why you would then need to define _AFXDLL, in order to compile/link any program you write which has nothing to do with MFC, is quite beyond me....

                    1 Reply Last reply
                    1
                    • C Offline
                      C Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on 1 May 2023, 13:28 last edited by
                      #10

                      As @JonB said, if you're done with MFC you need to remove linking against its libraries. That's where the appmodul.cpp comes from in your callstack. Defining _AFXDLL is not a proper solution. It just marks your app as a standalone MFC module so that it does not declare global state in it. It does not remove MFC from your app.
                      Go to your project settings and in the Advanced section disable MFC in the "Use MFC" field.

                      1 Reply Last reply
                      2

                      7/10

                      1 May 2023, 12:48

                      • Login

                      • Login or register to search.
                      7 out of 10
                      • First post
                        7/10
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved