- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I've converted a big fortran program to a dll and I use this dll from a delphi program.
It works fine BUT when some parameters are wrong my fortran code calls STOP statement.
Then my delphi application crash without any messages.
Someone has got a solution ?
Link Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Don't use STOP. That's what STOP does - it exits the program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know that, but the STOP statement is called from a library that I can't modify. My client could perhaps do it but what should he use instead of STOP statement?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
We have Fortran DLLs that we call from Visual Basic or C# programs (the VB or C# provides the GUI, the Fortran does the calculations), and one method we use to get a useful warning or error message from the Fortran DLL back to the calling routine is toreturn an integer variable as the warning/error flag and pass a string to contain the warning/error message. This is similar to other API routines that return an integer value to indicate successful completion or an error. Rather than a long list of various error codes, I prefer having a stringwith a message. For example, in our DLLthe integer variable would be returned as 0 if no error, returned as 1 for a non-fatal warning, or returned as 2 when an error has ocurred. You could certainly have more integer values for various levels of severity on the warnings and errors. We then display the warning or error message to a pop-up message box or to a text box in the GUI, and write it to a text log file. Hopefully the message is meaningful enough that the user can change an input and try running the calculation again.
When an error occurs in a routine inthe Fortran DLL (due to a trapped error or a check on an invalid input value),set the integer variable flag and the message string values, then use the RETURN rather than STOP to exit the Fortran routine. For our program, using RETURN exits from the Fortran DLL and returns to the calling program. For a larger DLL with many routines, I have added a check on the integer flag variable after each subroutine call. If there was an error, then that routine also exits using RETURN, checking after each routine call all the way back up to the top routine in the DLL to exit the DLL.
A few other details I've noticed when using a Fortran DLL that is called by another language is to add the extra code to clean up any allocated variables and open filesbefore exiting the DLL. Since I would like the user to change an input and run again, I need to be careful to not allocate an already allocated array. Since the DLL stays in memory while the program is running, I recommend putting a check on any allocatable arrays before allocating them, and specifically deallocating arrays when exiting a routine. Also be sure to close any files that have been opened in the DLL, and add a check when opening or closinga file. Add error trapping, such as the ERR and END parameters in Fortran commands like OPEN and WRITE statementsto trapany unexpected error so that you can set your integer flag and message string rather than having the DLL just crash with a system error. Once the Fortran DLL has been made "crash proof" it is much more user friendly to correct any input errors and run again.
Another approach we have used is to have a Fortran executable, an input file, and run the system command from the main program. For example, our GUI gathers the user inputs and writes the values to an input file. The GUI then gives a system command to run the Fortran program (as if we had entered the command at the system prompt), and waits for it to complete. Any errors are written by the Fortran program to a file, that is checked by the main program. If the Fortran program crashes due to an unexpected problem, at least the main GUI doesn't crash too. This digresses a bit from your question about using STOP in a DLL.
If others have methods to trap and return errors from a DLL I would like to hear about the possibilities.
Does this help answer your question about STOP versus RETURN in a DLL?
Regards,
Greg
We have Fortran DLLs that we call from Visual Basic or C# programs (the VB or C# provides the GUI, the Fortran does the calculations), and one method we use to get a useful warning or error message from the Fortran DLL back to the calling routine is toreturn an integer variable as the warning/error flag and pass a string to contain the warning/error message. This is similar to other API routines that return an integer value to indicate successful completion or an error. Rather than a long list of various error codes, I prefer having a stringwith a message. For example, in our DLLthe integer variable would be returned as 0 if no error, returned as 1 for a non-fatal warning, or returned as 2 when an error has ocurred. You could certainly have more integer values for various levels of severity on the warnings and errors. We then display the warning or error message to a pop-up message box or to a text box in the GUI, and write it to a text log file. Hopefully the message is meaningful enough that the user can change an input and try running the calculation again.
When an error occurs in a routine inthe Fortran DLL (due to a trapped error or a check on an invalid input value),set the integer variable flag and the message string values, then use the RETURN rather than STOP to exit the Fortran routine. For our program, using RETURN exits from the Fortran DLL and returns to the calling program. For a larger DLL with many routines, I have added a check on the integer flag variable after each subroutine call. If there was an error, then that routine also exits using RETURN, checking after each routine call all the way back up to the top routine in the DLL to exit the DLL.
A few other details I've noticed when using a Fortran DLL that is called by another language is to add the extra code to clean up any allocated variables and open filesbefore exiting the DLL. Since I would like the user to change an input and run again, I need to be careful to not allocate an already allocated array. Since the DLL stays in memory while the program is running, I recommend putting a check on any allocatable arrays before allocating them, and specifically deallocating arrays when exiting a routine. Also be sure to close any files that have been opened in the DLL, and add a check when opening or closinga file. Add error trapping, such as the ERR and END parameters in Fortran commands like OPEN and WRITE statementsto trapany unexpected error so that you can set your integer flag and message string rather than having the DLL just crash with a system error. Once the Fortran DLL has been made "crash proof" it is much more user friendly to correct any input errors and run again.
Another approach we have used is to have a Fortran executable, an input file, and run the system command from the main program. For example, our GUI gathers the user inputs and writes the values to an input file. The GUI then gives a system command to run the Fortran program (as if we had entered the command at the system prompt), and waits for it to complete. Any errors are written by the Fortran program to a file, that is checked by the main program. If the Fortran program crashes due to an unexpected problem, at least the main GUI doesn't crash too. This digresses a bit from your question about using STOP in a DLL.
If others have methods to trap and return errors from a DLL I would like to hear about the possibilities.
Does this help answer your question about STOP versus RETURN in a DLL?
Regards,
Greg
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using STOP or otherwise not returning to the calling program is a really bad way of handling this sort of error. I call DLL's from Excel, and if the DLL fails to return, Excel will hang, you cannot save your workbook, ...
Rather than STOP, it would be better than the DLL returns an error code or unusual return value which the caller can handle as an error.
David
Rather than STOP, it would be better than the DLL returns an error code or unusual return value which the caller can handle as an error.
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
+1 calling STOP from any "library" type code is bad practice. Today that code might be in a console application that doesn't matter, but tomorrow it might be in a DLL called by Excel or Matlab, or linked into a stand-alone GUI application. Better to think about error handling and recovery ahead of time. Not having an iostat argument on things like open statements is also problematic, even simple write statements to the console - the program may not always have a console to write too.
As an extension of the idea to always pass some sort of error flag between procedures, I use a derived type to encapsulate errors, warnings, informational messages, etc. It includes things like a severity level, a code (for cross-referencing in documentation), component that generated the error, descriptive message etc. Procedures that can generate more than one error in a call have an allocatable array of these objects as an argument. Supporting procedures and defined operations help simplify common operations, like testing for success and printing to the console (until we get DTIO in ifort). There are also "procedures" for converting the derived type to something more appropriate for other languages or environments, such as a C++ exception or matlab structure or a simple message box in excel, etc.
As an extension of the idea to always pass some sort of error flag between procedures, I use a derived type to encapsulate errors, warnings, informational messages, etc. It includes things like a severity level, a code (for cross-referencing in documentation), component that generated the error, descriptive message etc. Procedures that can generate more than one error in a call have an allocatable array of these objects as an argument. Supporting procedures and defined operations help simplify common operations, like testing for success and printing to the console (until we get DTIO in ifort). There are also "procedures" for converting the derived type to something more appropriate for other languages or environments, such as a C++ exception or matlab structure or a simple message box in excel, etc.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page