Structure of a Visual Fortran Application

To understand how Visual Fortran handlers are incorporated into your application, and how you might incorporate your own handlers, you should understand how each application type is constructed. The following sections describe handlers for the various application (project) types:

Fortran Console Applications

Fortran Console applications actually look like C applications under the hood, with the Visual Fortran run-time system providing the C main() function.

The entry point for a console application is specified as the C library's mainCRTStartup() routine (see module crt0.c in the C run-time sources). This initializes the C run-time system, wraps the Fortran run-time system main() in a try-except construct using the C run-time's exception filter (_XcptFilter()), and calls the Fortran run-time system main() routine in run-time module for_main.c. In simplified form, it looks like this:

   mainCRTStartup()
  {
     C initialization code here
     __try {
          more initialization code here
          mainret = main()      /* calls Fortran run-time main() */
          exit(mainret)
     } __except ( _XcptFilter() )
            { _exit ( GetExceptionCode() ) }
  }

In the Fortran run-time system, main() initializes the Fortran run-time system (if not already initialized), wraps a try-except construct around MAIN__ (the entry point to the Fortran code) with a filter expression that invokes the Fortran run-time system default handler on exceptions, and calls MAIN__. It also wraps a try-finally construct around all of this so run-time system clean up gets done (with FOR_RTL_FINISH_) when the program exits. In simplified form, it looks like this:

  main()
  {
     __try {
        __try {
              for_rtl_init()
              MAIN__
        } __except ( expression-invoking-fortran-default-handler )
                 { }
     } __finally { for_rtl_finish() }
  }

In the Fortran code, symbol MAIN__ is the entry point called by the run-time system's main() routine. MAIN__ has the code to do any further run-time initialization or checks. For example, if the user compiled with the non-default /fpe:0 option, there would be a call to FOR_SET_FPE to tell the run-time system how to setup/react to floating-point exceptions.

Fortran QuickWin and Standard Graphics Applications

A Fortran QuickWin (including Fortran Standard Graphics) application is a specialized windows application where Visual Fortran provides the WinMain() function.

The entry point for a QuickWin application is specified as the C library WinMainCRTStartup() routine (see module crt0.c in the C run-time sources). This gets the C run-time initialized, wraps the Visual Fortran defined WinMain() in a try-except construct using the C run-time exception filter (_XcptFilter()) and calls the Visual Fortran defined WinMain() routine. In simplified form, it looks like this:

  WinMainCRTStartup()
  {
     C initialization code here
     __try {
           more initialization code here
           mainret = WinMain()      /* calls CVF qwin library WinMain() */
           exit(mainret)
     } __except ( _XcptFilter() )
              { _exit ( GetExceptionCode() ) }
  }

In the QuickWin library, WinMain() performs some initialization specific to QuickWin, creates a new thread which begins execution at QWINForkMain, and then sits in a message loop directing the action. The message loop is wrapped in a try-except-finally construct which invokes the Fortran run-time system default handler if an exception occurs, and calls FOR_RTL_FINISH_ at exit. QWINForkMain() running in the other thread calls the Fortran run-time system main(), which in turn calls MAIN__. In simplified form, it looks like this:

  WinMain()
  {
     Initialization code here
     BeginThreadEx (..., QWINForkMain, ... )
     __try {
        __try {
              the message loop...
              for_rtl_finish()
              return (msg.wParam)
        } __except ( expression-invoking-default-fortran-handler )
                 { }
     } __finally {
           for_rtl_finish()
           return (msg.wParam)
     }
  }

QWINForkMain resembles the following:

  QWINForkMain()
  {
     main()      /* calls the CVF rtl main() which calls MAIN__ */
     cleanup and exit...
  }

The routines main() and MAIN__ are the same as previously described for a Fortran Console application.

Fortran DLL Applications

A Fortran DLL is a collection of one or more routines that you generally call from some other main program. As such, the routines execute in the structure and environment created by the code which calls into the DLL. You can provide DLL initialization through a DllMain() function, but you probably would control general application initialization from the main program.

There are no automatic provisions for any exception handler in a DLL. There is no environment initialization except what you provide. Of course, if your main application is also written in Fortran, you will get the default Fortran handlers provided by that application type.

Fortran Windows Applications

A Fortran Windows application has as its entry point WinMainCRTStartup() and each user writes the code for the WinMain function declaration and interface. Examples are provided to show how to do this in Fortran code. The compiler still generates symbol MAIN__ with the initialization code in place, but nothing calls MAIN__. Also, nothing connects up to the run-time system's main() so there's no try-except construct to hook in the default Visual Fortran handler, and no run-time system initialization or cleanup. In simplified form, it looks like this:

  WinMainCRTStartup()
  {
     C initialization code
     __try {
           more initialization code
           mainret = WinMain()      /* calls the user's WinMain() */
           exit(mainret)
     } __except ( _XcptFilter() )
              { _exit ( GetExceptionCode() ) }
  }

The Fortran code contains:

  integer(4) function WinMain( HANDLE, HANDLE, LPSTR, int )
  ...
   ! whatever Fortran the user codes here...
  ...
  end