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

Using a Fortan DLL in VB that has a STOP command

alanbcole
Beginner
5,726 Views
I am looking for a suggestion on how to handle the following problem. My dll file is running older Fortran code that on a error goes to an error handling subroutine that uses the STOP function to end the program. This inturn closes my VB application. I would like the VB application to stay open so i can read my error file and report it. Thanks
0 Kudos
38 Replies
billaustralia
Beginner
2,418 Views
This problem keeps arising. It has a very simple but inelegant solution.

replace the stop by
i=1
i=1/0

Why does this work. As far as my limited understanding goes, some errors in vf are caught by error handlers in vb and vba. Others are not. STOP is not and so the VF finishes and the vb and vba stop and sometimes hang.

But integer division by zero is caught and so the call stack is unloaded and the vb sees an err=11 error which can be treated in the usual vb way with
on error resume next etc.

I have now been using this successfully for 4 years on both Lahey and VF

On entry to the vf from vb I set an error code to error, and only reset to no error just before normal return to vb. Thus any unexpected return to vb (eg some file errors also cause immediate return to vb) is picked up by my coding in vb.
0 Kudos
billaustralia
Beginner
2,418 Views
small correction..
replace STOP by
i=0
i=1/i
as the compiler will make 1/0 as an error
0 Kudos
gfthomas8
Novice
2,418 Views
I think you missed the OP's constraint on not being able to change the dll's source code. The cleanest solution is to simply eliminate the STOP which should never have been there to begin with.

Ciao,
Gerry T.
0 Kudos
billaustralia
Beginner
2,418 Views
well gf what can I say.

At the time my code was first written (1974)!) Stop was the accepted method of finished a fortran program.

In the code there are several hundred calls to the exit routine. No provision at all in the calls for return in case the application wishes to quit.

To say that the stop should simply be eliminated is just breathtaking. I mean if we can rewrite the past, I choose to be 10 years old again.

In any case eliminating the stop statement IS a change in the source code.
0 Kudos
gfthomas8
Novice
2,418 Views
In 1974 there was no Windows OS and no DLL's.

Today, one STOP in a DLL is one too many.

There was one viable suggestion made in the thread for eliminating the STOP _without_ changing the source code.

Ciao,
Gerry T.

0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,418 Views
Bill, isn't it nicer to make a wrapper, e.g.
subroutine Stop()
!DEC$IF DEFINED (_DLL)
use DFWIN, only: RaiseException, NULL
integer, parameter:: MyException = Z"AC1DBABE"
call RaiseException(MyException,0,0,NULL)
!DEC$ELSE
stop
!DEC$ENDIF
end subroutine Stop()
Jugoslav
0 Kudos
billaustralia
Beginner
2,418 Views
Thanks for the reply.

I have tried it in debug mode and get popup with title
Compaq Visual Fortran
and text
Unhandled expection in excel.exe (KERNEL32.DLL): 0xAC1DBABE: (no name)

The excel task disappears.

My vf is

subroutine Test(i)
!DEC$IF DEFINED (_DLL)
use DFWIN, only: RaiseException, NULL
integer, parameter:: MyException = Z"AC1DBABE"
if (i.eq.7)then
i=i/0
else
call RaiseException(MyException,0,0,NULL)
endif
!DEC$ELSE
stop
!DEC$ENDIF
end subroutine Test
SUBROUTINE VfTest(I)
!DEC$ ATTRIBUTES DLLEXPORT :: VfTest ! This exports the name
!DEC$ ATTRIBUTES ALIAS : "VfTest" :: VfTest !This sets it
call Test(i)
i=i+10
end

My vba in Excel is

Option Explicit
Declare Sub VfTest Lib "H:SgastlibwwDebugww.dll" (i As Long)

Sub w()
Dim i As Long
i = 6
On Error Resume Next
Call VfTest(i)
If Err > 0 Then MsgBox Error(Err) & Str$(i)
End Sub

Am I doing something wrong?

If I put i=7 it works ok and the vba msgbox
Division by zero 7
appears in Excel showing that the i=i+10 has not been executed.
The macro can be executed again.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,418 Views
Does it work when ran outside the IDE/debugger?
IMO it should.

You set the debugger's behaviour on exceptions on Debug/Exceptions (you have to be in Debug mode). Type AC1DBABE (I made up the number, obviously), give it a name (e.g. "My dll stopped") if you like and check "Stop if not handled".

Of course, you can still use 1/0. instead of RaiseException (although RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO) should do the same thing). My point was rather that you should isolate stopping code in a separate, platform-specific routine in order not to pollute the original code.

Jugoslav
0 Kudos
billaustralia
Beginner
2,418 Views
Thanks for your patience on this.

I get the same result running outside the debugger

What is 'IMO'

I had not used exceptions at all.

When I do as you suggest with AC1DBABE, I get the same result.

EXCEPTION_FLT_DIVIDE_BY_ZERO is not defined on my set up so I used c0000094 Integer Divide by Zero and it worked exactly as my divide by zero.

Is it that the error raised has to be one that is handled by vba (excel 97 in my case)? Maybe both AC1DBABE and STOP are not handled so excel fails. Integer divide by zero is so it goes back to excel.

I also tried using float overflow c0000091 and that also returned to excel ok.

Maybe there is some way to get vba to handle a vf user defined exception?
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,418 Views
What is 'IMO'

= in my opinion

Is it that the error raised has to be one that is handled by vba (excel 97 in my case)? Maybe both AC1DBABE and STOP are not handled so excel fails. Integer divide by zero is so it goes back to excel.

It looks as if it's true. I don't know much about VBA; I assumed On Error would handle any exception, but I might be easily wrong. Note that STOP cannot be "handled" -- it's not an exception, but an unconditional call to ExitProcess. User-defined exceptions are definitely handleable in e.g. C++ and Delphi, but perhaps it's not the case in VBA. Perhaps someone more versatile in VB, like Gerry or Marco, could comment.

Just out of curiosity, try raising C000008C (Array bounds exceeded) and C0000097 (user-defined, but within numerical range of system exceptions). Does any of these work?

Jugoslav
0 Kudos
billaustralia
Beginner
2,418 Views
No both of those give unhandled exception in debug mode, and a windows system error in excel outside debug mode causing excel to fail.

I pick up anything that returns to vba by setting my err argument to error immediatly on entry to the vf dll, and only reset to no error just before a normal return. Hence in the vba I can tell if an unexpected return occurred.

I plan to retain use of i=i/0 for 2 reasons
) I coded it in some years ago
) it also works in Lahey Fortran

I would be very interested to hear of anyone else who finds this a practical solution. What about you alanbcole? Does it solve your problem?
0 Kudos
gfthomas8
Novice
2,418 Views
> I don't know much about
> VBA; I assumed On Error would handle any
> exception, but I might be easily wrong.

You're more right than wrong. VB6's Err object can handle many but not all exceptions thrown at it. In some cases it even gets confused, eg, it fails to distinguish between overflow and underflow and has done so since VB4.

> Note that
> STOP cannot be "handled" -- it's not an exception,
> but an unconditional call to ExitProcess.

How true.

> User-defined exceptions are definitely handleable in
> e.g. C++ and Delphi, but perhaps it's not the case in
> VBA.

In VB.NET C/C++-style and SEH are supported. One can implement exception handling in VB6 but why do so in this instance where the exception is thrown in a Fortran DLL and left unhandled to fall thro' the cracks to VBA who would rather not have to deal with it but pays the price if it doesn't. The Fortran DLL should handle any exception thrown by it and the CVF docs clearly shows how to do so with working samples thrown in. As you've mentioned, the STOP in the DLL should be replaced by an appropriate RaiseException and IMO this should be handled by the DLL. The problem with the divide by zero hack is that from VBA one can change the cw to mask such fp exceptions as thown in the DLL with which you're finished.

Ciao,
Gerry T.
0 Kudos
themadcapz
Beginner
2,418 Views
Hello All,

I am also working with a program that was written in Fortran and we recently completed conversion to a DLL.

The program is littered with STOP statements and we need to remove them so that we can exit the program gracefully with error information being provided to the user. We can make changes to the source code to accommodate this change.

The only catch to this is a lot of the STOP statements are in functions and I need a way to catch an error in the function and pass an error code back to the calling routine.

Would it possible to use the RESULT variable when calling the function?

What would I do in the case of a logical function? how would I pass an error code value back from this?

Any help is greatly appreciated
0 Kudos
jeffrey_t_b
Beginner
2,418 Views
We had a similar problem in a fortran library that we were going to use within a C++ wrapper. (There was an additional problem of supporting legacy fortran applications that linked directly to the fortran lib.) The approach that we took was to replace all STOP calls with a call to a "quit" function. The quit function was implemented in the lib as a simple call to STOP. Then, the C++ library re-implemented quit() (i.e. replaced the fortran lib version) using exception handling / etc.
0 Kudos
wjturner
Beginner
2,418 Views

I too had this problem nearly 10 years ago when I first converted my old fortran exe to a Lahey Fortran dll. The solution given in my earlier posts worked then and continues to work well in CVF, IVF6 and IVF7. The solution is a follows:

in vb or vba

on error resume next
ErrReturn = 0
Call FortranDllRoutine(ErrReturn)
If Err=4 and ErrReturn > 0 then
'Fortran sub Error has triggered return
' read fortran error message from file
else
'some file errors also trigger a return
Endif

In Fortran

Subroutine FortranDllRoutine(ErrReturn)
ErrReturn=1
Call Sub1
ErrReturn=0
End
Subroutine Sub1
Call Sub2
End
Subroutine Sub2
Call Sub3

etc etc

Subroutine Sub99
!write error message to a file
Call Error
End
Subroutine Error
I=0
I=I/0
! this terminates and returns direct to the vb
End

0 Kudos
wjturner
Beginner
2,418 Views

Sorry correction

Subroutine Error
I=0
I=1/I
! this terminates and returns direct to the vb
End

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,418 Views

STOP generates the following code:

call _for_stop_core

Replace "_for_stop_core" with your own routine. Then relink the DLL.

Jim Dempsey

0 Kudos
Intel_C_Intel
Employee
2,418 Views
I had a similar problem a few years ago. The only solution I could find was to rewrite every pathway that led to the STOP and re-engineer it to pass return up the chain to the calling VB program. It wasn't rocket science, but it required detailed knowledge of the code and patience.
0 Kudos
Reply