Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Error?

reneeculver
Beginner
3,839 Views
The book arrived today!!!

Subroutine SetupExit
Use kernel32
Integer*4 FF
ff=SetupConsoleCntlrHandler(CloseWindow,.true.)
Return
End

Subroutine CloseWindow(number)
Integer*4 number
Return
End

I amcallingSetupExit but FFreturns a 1 which means an error ocurred. But what's the error?

Renee




0 Kudos
27 Replies
Steven_L_Intel1
Employee
3,011 Views
Renee,

I see several things wrong:

  1. The name of the function is SetConsoleCtrlHandler
  2. You did not declare CloseWindow as EXTERNAL (if it is a procedure in the same module, then you don't need to do that.)
  3. You passed .true. which is a Fortran LOGICAL value, not the C BOOL that the function expects. Use TRUE (declared in KERNEL32) instead
  4. The documentation for this function indicates that a zero return value indicates error. You would then call GetLastError to get a more detailed error code. A value of 1 indicates success.
  5. Any Windows callback function needs to be STDCALL. So you need to add "!DEC$ ATTRIBUTES STDCALL :: CloseWindow" to the CloseWindow routine itself and in the caller (again, this last is not needed if it is a module procedure.)
Note that the STDCALL attribute will also turn the argument for CloseWindow to be by value, which is what you want.
0 Kudos
reneeculver
Beginner
3,011 Views
I know but the copy for this forum is not working today. I spelled it correctly in the code. But the hand copy was fatal.


CloseWindow is immediately below so it is in the same module.

Let me go try the others.

Renee
0 Kudos
Steven_L_Intel1
Employee
3,011 Views
Is it in a MODULE or just adjacent in the source file? If not inside a MODULE (with CONTAINS before all the procedures), then you need EXTERNAL.
0 Kudos
reneeculver
Beginner
3,011 Views
When I add the IDEC to CloseWindow its fine, as far as the compile/link is concerned and it runs.

When I add it to SetupExit also, Irecieve the following error:

Error 1 error #7112: This actual argument must not be the name of a procedure. [CLOSEWINDOW] D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 2458

Renee
0 Kudos
Steven_L_Intel1
Employee
3,011 Views
You'll have to show me exactly what the source you changed says.
0 Kudos
reneeculver
Beginner
3,011 Views
I just recieved a Forrtl error of 200: Progran aborting due to a Window-Close event. This is the fitst time I've ever seen such an event.

Renee
0 Kudos
reneeculver
Beginner
3,011 Views
This is what the code is now:

Subroutine SetupExit

USE KERNEL32

integer*4 ff

ff=SetConsoleCtrlHandler(closewindow,TRUE)

Return

End




subroutine CloseWindow(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

Return

end

Where do I put the External?

By the way....TRUE remains undefined in the call to SetConsoleCtrlHandler.

Renee

0 Kudos
Steven_L_Intel1
Employee
3,011 Views
TRUE is a PARAMETER constant defined by the USE KERNEL32.

The EXTERNAL declaration goes in SetupExit.

The error 200 is caused by the Run-Time Library seeing an unexpected Window Close event. You might try adding this to your CloseWindow routine:

[fortran]    interface
    subroutine for_rtl_finish_ () BIND (C)
    end subroutine for_rtl_finish_
    end interface
    
    call for_rtl_finish_[/fortran]

After the declaration of "number". I don't know if that will help. What it does is tell the run-time library to shut down.
0 Kudos
reneeculver
Beginner
3,011 Views
The following compile and run:

Subroutine SetupExit

USE KERNEL32

integer*4 ff

ff=SetConsoleCtrlHandler(closewindow,TRUE)

Return

End


subroutine CloseWindow(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

Return

end

0 Kudos
reneeculver
Beginner
3,011 Views

With this source, I receive the following errors:

Subroutine SetupExit

USE KERNEL32

External Closewindow

integer*4 ff

ff=SetConsoleCtrlHandler(closewindow,TRUE)

Return

End

subroutine CloseWindow(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

Return

end


Error 1 error #7112: This actual argument must not be the name of a procedure. [CLOSEWINDOW] D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 2458

Error 2 error #5508: Declaration of routine 'AT' conflicts with a previous declaration D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 60

Error 3 Compilation Aborted (code 1) D:\System Utilities\Adventure\Adventure\Adventure(intel)\Adventure\ASUBS.FOR 1
0 Kudos
reneeculver
Beginner
3,011 Views

By the way, assuming you see the interface the way it's shown, I don't see it with numbers, although I see ms code with numbers.

Unfortunately the book hasn't done me much good. Neither "USE" or "External" are in the index. I need a book on Keywords.

Renee

0 Kudos
IanH
Honored Contributor III
3,011 Views
Which book did you get?
0 Kudos
psantos
Beginner
3,011 Views
Could you tell us the book you are using? Perhaps you should search for the word "module".

Pedro
0 Kudos
mecej4
Honored Contributor III
3,011 Views
> But what's the error?

If you had used IMPLICIT NONE, you would have found out.

According to the rules of Fortran, CloseWindow is an uninitialized default REAL variable in SetupExit.
0 Kudos
IanH
Honored Contributor III
3,011 Views

Here you go - have a look at this. Note your callback needs to be a function too. This is free form source (if you copy it to a file on your computer use the .f90 extension).

[fortran]

! We'll put out utility routines into a module. That helps the compiler check ! that we are calling the routines correctly (amongst numerous other benefits). MODULE RoutinesForHandlingTheConsole IMPLICIT NONE ! Avoid bugs due to typos and confusion about type. CONTAINS ! Subroutine for us to call when we want to install our console event ! handler. SUBROUTINE SetupExit ! Intel provide with the compiler a series of modules which already have ! the "interface definitions" of the commonly used Windows operating ! system calls (Windows API) and associated types and constants. KERNEL32 ! contains the SetConsoleCtrlHandler interface (and probably a thousand ! other things). We use the ONLY clause to document where the interface for ! SetConsoleCtrlHandler (and the definitions of some of the other constants ! that we need) came from. USE KERNEL32, ONLY: SetConsoleCtrlHandler, BOOL, TRUE !--------------------------------------------------------------------------- ! Local variables ! Under the windows api true and false are actually represented by a ! particular kind of integer, rather than by the LOGICAL type from the ! fortran language. INTEGER(BOOL) :: ff !*************************************************************************** ! Tell the operating system what we want our handler function to be. The ! TRUE value for the second argument tells the operating system that ! we want to Add the handler. Documentation for SetConsoleCtrlHandler is ! online at: ! http://msdn.microsoft.com/en-us/library/ms686016%28v=vs.85%29.aspx ! (But it is written for C/C++ programmers, not Fortran programmers). ! ! The LOC intrinsic function is an extension provided by ifort that ! converts the address of the procedure into an integer (this is how ! addresses are/were handled historically when interfacing Fortran ! programs with the windows API). ff = SetConsoleCtrlHandler(LOC(CloseWindow), TRUE) END SUBROUTINE SetupExit ! Our handler routine. As per the Window API documentation this needs to be a ! function that returns a BOOL (C declaration - INTEGER(BOOL) in Fortran). It ! must take a single DWORD (C declaration - in Fortran INTEGER(DWORD) is the ! equivalent) argument that describes the type of event to be handled. ! ! A return value of FALSE means the event should be passed onto the next ! handler in the chain. A return value of TRUE means that no further event ! handlers will be called (the event has been processed). ! ! Documentation for the handler routine is online at: ! http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx ! ! Documentation is also available from within Visual Studio (press F1!). FUNCTION CloseWindow(number) ! As per the USE statement comment above. USE KERNEL32, ONLY: BOOL, DWORD, TRUE, FALSE ! Function result type INTEGER(BOOL) :: CloseWindow ! We need the calling convention of CloseWindow to match what the ! windows operating system expects - that's STDCALL (on 32 bit windows). !DEC$ ATTRIBUTES STDCALL :: CloseWindow ! Our argument type. Because this routine is STDCALL, and this is a scalar, ! this argument will be passed by value (which is what we want per the docs). INTEGER(DWORD), INTENT(IN) :: number !**** ! Meaning of number based on the online documentation. SELECT CASE (number) CASE (0) ! Ctrl c PRINT "('Oi!! Stop pressing Ctrl-C!')" CloseWindow = TRUE CASE (1) ! Ctrl break PRINT "('Ouch!! That Ctrl-Break hurt!')" CloseWindow = TRUE CASE (2) ! Console Window close PRINT "('Wait a tick - I don''t want to go away!')" CloseWindow = TRUE CASE DEFAULT ! 5 for log off, 6 for shutdown - ! We'll indicate that we want the next handler (which should be the ! fortran runtime) to deal with this, because the user is being ! pretty serious about leaving! PRINT "('Bye bye!!')" CloseWindow = FALSE END SELECT END FUNCTION CloseWindow END MODULE RoutinesForHandlingTheConsole PROGRAM RENEE_1 ! Make available our utility procedures. USE RoutinesForHandlingTheConsole ! For testing we'll run a little loop to take up some time. Each loop ! iteration we'll sleep - intel provide a "Sleep" function to let us ! do that (we could also go directly to sleep routines in the Windows ! API). USE IFPORT, ONLY: SLEEPQQ IMPLICIT NONE INTEGER :: i ! Loop counter !***************************************************************************** ! Install our console handler CALL SetupExit PRINT "('Go ahead - make my day (try Ctrl-C/Ctrl-Break/Close my window!')" DO i = 1, 20 PRINT "(I0)", i CALL SLEEPQQ(500) ! Sleep for half a second END DO END PROGRAM RENEE_1[/fortran]
0 Kudos
reneeculver
Beginner
3,011 Views
I got the Compaq VF book...of course it doesn't have module in the index either.

I cant use Implicit none because I am working on the oldest game written on computers and it already has Implicits declared.

But the real help's alot. The error messsages have not changed and my code is:

Subroutine SetupExit

USE KERNEL32

External Closewindow1

Real ff

ff=SetConsoleCtrlHandler(closewindow1,TRUE)

Return

End

subroutine CloseWindow1(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

Return

end





Renee
0 Kudos
reneeculver
Beginner
3,011 Views
It was the Loc.

I've never heard of a LOC...it has not been mentioned and it's not in the index either.

Renee
0 Kudos
reneeculver
Beginner
3,011 Views

Function CloseWindow1(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

Return

end

Ok, it compiles and runs. and closewindow1 fires on windows closings (and no telling what else). But within the routine number comes in during window closings which I get now, as as undefined address.

Renee

0 Kudos
reneeculver
Beginner
3,011 Views

Subroutine SetupExit

USE KERNEL32

External Closewindow1

Real ff

ff=SetConsoleCtrlHandler(loc(closewindow1),TRUE)

Return

End



Function CloseWindow1(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

integer*4 number

stop

Return

end

So far, it works like this with no stack dumps.

I"d like to thank Steve and especiallly Ian. Thank you.

I still dont know why number was undefined at run time.

Renee

0 Kudos
IanH
Honored Contributor III
2,877 Views
Quoting reneeculver

Function CloseWindow1(number)

!DEC$ ATTRIBUTES STDCALL :: CloseWindow

Careful. 'CloseWindow1' .NE. 'CloseWindow'.

If that's not a transcription problem then CloseWindow1 wouldn't be being declared as StdCall. That has implications for stack cleanup and also how arguments are passed (number would be coming through as garbage attempts to reference number would almost certainly crash your program).

0 Kudos
Reply