topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Saturday December 7, 2024, 2:32 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: How to close a Fortran DLL routine when exiting Visual Basic (front-end) program  (Read 9147 times)

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Hi,

I'm having problems with my VB6 program that merges with a Lahey Fortran DLL.  It has been around for over 20 years!  The DLL was started around 5 or 10 years ago.  My VB6 program may call the DLL 1 or more times with no problems.  Then on closing, the program hangs!!!  If one doesn't call the DLL, no hanging occurs on closing.  Ideas?

1. Phil Brubaker
2. S/N: 001873...
3. Lahey/Fujitsu Fortran 95 Express Release 7.10.02
4. Patch level?
5. OS: Windows 7
6. Example VB6 code:
Private Declare Sub PSDcalc_for Lib "PSDcalc_for.dll" (ByVal fileNam As String, ByRef x_array As Single, _
  ByRef spectrum As Single, nptsZ As Integer, npointsZ As Integer, _
  t_startZ As Single, t_finalZ As Single, zeroFillZ As Single, sig2Z As Single, _
  nPoles As Integer, nZeros As Integer, M_eqs As Integer, M_lags As Integer, _
  Mode As Integer, L_pts As Integer, ByVal str_len As Long)
 
ooo

         ReDim x_array(1 To npointsZ) As Single, spectrum(1 To npointsZ) As Single
            x_array(1) = 1: spectrum(1) = 1
            ChDrive App.path:      ChDir App.path

            Call PSDcalc_for(fileTemp, x_array(1), spectrum(1), nptsZ, npointsZ, _
                t_startZ, t_finalZ, zeroFillZ, sig2Z, _
                nPoles, nZeros, M_eqs, M_lags, Mode, L_pts, _
                Len(fileTemp))

            If nptsZ < 1 Then
              MsgBox "File Error ... read bottom of your '~rainbow.out' file for " & vbCrLf _
                 & "more details. This OUT file is in the same directory " & vbCrLf _
                 & "as your input file; ... " & vbCrLf _
                 & "   " & fileTemp, vbOKOnly, "File name in error ... " _
                 & "read Output file for more"
              Call createFileOut(fileIn)
              Exit Sub
            End If
            Call createFileOut(fileIn)
ooo
-------------------------------------------------------------------------------------

F90 code:
------------
     Subroutine PSDcalc_for( fileNam, x_array, spectrum, nptsZ, &
           npointsZ, t_startZ, t_finalZ, zeroFillZ, sig2Z, &
           npolesZ, nzerosZ, M_eqsZ, M_lagsZ, modeZ, L_ptsZ)

        dll_export :: PSDcalc_for
        character(len=*) :: fileNam

        include 'spec_in.inc'

        complex signal_amp( :)
        real y_array( :), norm_factor
        real, dimension( npointsZ) :: x_array, spectrum
        allocatable :: y_array, signal_amp
--------------------------------------------------------------------------------------

This code works, can call PSDcalc_for several times ... AOK.  Then try closing my VB6 front-end and vb6 seems to hang.  Create an EXE for my project and it too runs fine until closing.  Then it tries closing and gets the same error msg.

This app has been running since 1994 (?) with no problem, what is new that causes such error?  I found a back-up with same DLL, back in 2015, and it too aborted with same error!  The app is not used that often by me, so unclear when this shutdown error msg. started.

Any ideas on how to close down my Fortran DLL, without forcing it just a 'normal' close?

Thanks, Phil

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
For Delphi i can use MadExcept to show me easy Errors or non-free'd objects.
I aint program in VB, does it provide Stacktrace? If so, what does it tell?

My guess is that you have some object open that raise a conflict at youre exit-code.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
VB, does it provide Stacktrace? If so, what does it tell?
Never heard of "Stacktrace" in VB nor Fortran ... where might I find it -or- try it?  How would you use it ... show me some code.

Thanks, Phil

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,190
    • View Profile
    • Donate to Member
The stack trace is from the exception and shows all of the stack frames that results in the execution path to the line in the code.

https://en.m.wikiped...org/wiki/Stack_trace

Article on MSDN about exception handlong in VB

https://msdn.microso...ibrary/ms973849.aspx

you should also be able to break in the debugger to get the same

using breakpoints on MSDN

https://msdn.microso...ibrary/5557y8b4.aspx





KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
How would you use it ... show me some code.
-OptimalDesigns (July 18, 2018, 10:57 AM)
Hello Phil,
thanks god wraith808 answered, i would have wrote something like that
Visit MadExcept Homepage to get an idea what it does, look at screenshot collection.
Sorry i have no idea if such exist in VB since it isnt my programming language.

How i use it? I just include a file in my project, set up a define, thats all. MadExcept works automatic.
When a program of me crashes where i've included MadExcept, you get a fancy MessageBox with more options and informations.
For your case i would enable a "ReportMemoryLeaks" define, thats all what i need to do in my code. As soon as i quit my App and something isnt free'd yet, MadExcept show me what, the "why" you have to investigate afterwards.

Same Results you get if you debug your code. I would do something like that: (in hope VB have such features)
 - Set up a breakpoint on first line of your exit code
 - Run program normal (inside VB-Studio), work a little with dll functions, close app
    in theory now your debugger should pop-up at first line of your exit code.
    from there trace into code, step-by-step, watch whats on stack
    step so long into; up to the moment when it crash, since your in debugger you see everything in realtime and should be able to locate error.

At least this way i would do it.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Over my head!!!  Guess I'll just leave it for someone else to work on.

Thanks for your efforts KodeZwerg and wraith808,
Phil

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Last i can do:
If your dll is available somewhere and you have full headers to it, i could check-out with Delphi if error is in dll or your Application.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Yes it is downloadable from http://fortrancalcul...o/misc/download.html page.  It is the SpectrumSolvers app ... includes all source files.  The DLL is named PSDcalc_for.dll and once downloaded and installed, the DLL is found in the \od-tools\SpectrumSolvers directory.

Thanks your your efforts.
Phil
PS:  The app closes fine -unless- the DLL is executed.  If the DLL is executed, it hangs the app when trying to close the VB app.

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
PS:  The app closes fine -unless- the DLL is executed.  If the DLL is executed, it hangs the app when trying to close the VB app.
I apply download this evening, tomorrow i should be able to give you a statement.
I will debug and see what this dll does during execution. I will try rebuild your Post #1 to Delphi and see what happens.

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
edited
I was bored @work, quick get your download, by reading the source (i just guess whats what in that language) things that i found remarkable:
good news, i figured out that dll is just one function. *hoorray*

in that function are many "write()" commands, i guess that you develop a console application then, right? for me it would be bad to call write() events from dll.
-Okay, now i know that it writes a file, sorry for that.

what i think is way critical, if it is a console dll, there are "call timer()" events, my very first idea = bad. (i should need information what that language means with "call timer()")
-Okay, no console App, sorry for that, i investigate that deeper.
-My stomach tells me that dll could hang in one of those many repeats and loops and for and goto things when you try to close calling application.
-If you are able to Thread it, i would thread that operation. A dll is not the best way to accomplish what you are doing.
-My suggestion would be: rewrite that dll method so you get as result whatever content you wish to write to file inside your VB App and apply the file-writing -stuff there. Most important would be something like a "i am ready" message/boolean/whatever that your VB need to wait for.

next i see alot of "Allocate()" commands but somehow no "De-Allocate()" or however its name should be.
-Sorry, now found some DeAllocate().
« Last Edit: July 19, 2018, 02:43 PM by KodeZwerg »

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Try running the app's demos and see what is going on.  Many runs and all is well.  Then try exiting the app.  It hangs!  Many DLLs show a wx_close() or w?_close() routine that does the job.  But out of my range.


KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Hello Phil,

with Delphi there happen no error (okay i cannot argue with that dll correct since i absolutely have no idea what you are doing there at all, some kind of calculation happen and a file is generated).

So i've tried to analyze your main executable. Running with two different debuggers = no real result.
Problem is that VB generate strange code, very hard to debug for me. I get alot of floating calculation errors even before the main executable is loading dll.

From my point of view the problem is somewhere in VB main executable and not DLL.
I have same result, closing App wihtout using DLL = no Problem, running DLL once = App crash on exit.

Please go through this checklist: (i hope VB code is same like other languages)
every "Open" needs a "Close", every "Create" needs a "Free", every "Allocate" needs a "DeAllocate", every "Attach" might need to be "Dettached" and so on.
Take a close look with everything that happen inside VB when DLL is used (ie: generate a picture, allocate stuff to do that, create image etc) and if you really "close/finalize" everything what was used during DLL interaction.

I am sorry if my english is bad/hard to read, but i hope you know what i try telling.

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Please do me a favor, create a new VB Project, just include a Button and do a fake DLL call. (fake = just fill parameter with something to be able to start that function)

Does that sample Application hang too?

This way you can verify if it is VB code in main Project (what my feeling tell that there is something wrong) or if VB has a generic problem with that DLL at all.

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,190
    • View Profile
    • Donate to Member
So you tried using the DLL in Delphi and calling functions and it unloaded correctly?  Where you dynamically loading the DLL or did you statically link it?

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
So you tried using the DLL in Delphi and calling functions and it unloaded correctly?  Where you dynamically loading the DLL or did you statically link it?
Static, unloads without error on Application Close.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
The following VB code give an error when trying to execute it ... ideas where my problem is?
---
      If EndDLL("PSDcalc_for.dll") Then MsgBox "It worked!"
---
The VB debugger says 'EndDLL' expected variable or procedure, not module.  Hmm, "EndDLL" is a function as described next.
---
Public Function EndDLL(DllReturnValue As Long) As Boolean

'PURPOSE: End a process started with VB's Shell Statement
'INPUT: Task ID returned by Shell
'RETURNS: True if succesful, false otherwise

On Error Resume Next

Dim hInst As Long
Dim hProcess As Long
Dim lExitCode As Long
Dim lRet As Long

hInst = DllReturnValue
If hInst = 0 Then Exit Function

'Get handle to process
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, hInst)
If hProcess <> 0 Then
    'get exit code
    GetExitCodeProcess hProcess, lExitCode
        If lExitCode <> 0 Then
                'bye-bye
            lRet = TerminateProcess(hProcess, lExitCode)
            EndDLL = lRet > 0
        End If
End If
End Function
---

KodeZwerg, you are probably right on the problem is in my VB -exit- code ... not the DLL.   On the inet the talk is about 'Close' vs. 'Close All'.  Ideas?

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,190
    • View Profile
    • Donate to Member
Is your DLL stdcall?

From just that bit of code, I think it's on your VB side, as that sort of calling (using the shell statement) is not something I've seen used for DLLs.  From my experience, that's used in shelling out to an executable.

How is your declaration done?  And how is your DLL called?  That seems different from what you've posted above.

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
What i see is absolutely a no-go. No wonder that Application hang if you try to kill Processes at end. A DLL aint a process.
CreateProcess() TerminateProcess() and such are made to run/kill external Applications, not DLL.

I have no time ATM, will come back later and post how to correct call a DLL with VB. (i have to search "how-to" for VB.... not my territory)

Ps: with Delphi i used stdcall convention and it worked.

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,190
    • View Profile
    • Donate to Member
What i see is absolutely a no-go. No wonder that Application hang if you try to kill Processes at end. A DLL aint a process.
CreateProcess() TerminateProcess() and such are made to run/kill external Applications, not DLL.

I have no time ATM, will come back later and post how to correct call a DLL with VB. (i have to search "how-to" for VB.... not my territory)

Ps: with Delphi i used stdcall convention and it worked.

That's not what he has in his code example is my concern.  But as for an example:

http://computer-prog...eb9fb0a7df21d33e.htm

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Hello again, as more i read about VB and working with DLL as more confused i get.
Many informations lead into a direction that VB need some kind of special prepared DLL. (i think wraith808 link write something similar)
Above i think isnt needed since your App can work with Dll.

But how you work with Dll, there is something very buggy.

I've been reading on Microsofts Visual Studio Site (in German) and its so much input, you could fill books with it.
Very complicated for me to a) translate all that expert stuff to english and b) understand it by myself.
It would make no sense if i copy and paste "something" and have no clue what i pasted.
Thats far out of my scope, i am sorry!

With the programming language i use, i just type something like this, thats all i need:
function ExampleCall ( SomeParameter: ParameterType ): ResultType; stdcall; external 'Some.dll';
This would enable me to use "ExampleCall" from "Some.dll", i do not need to (un)load that dll, all happen automatic this way.

I feel sorry for not being able to help any deeper.
« Last Edit: July 23, 2018, 04:49 PM by KodeZwerg »

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
What i suggest you should do:

Post your code where you define that dll call. (like i did in my previous post " ExampleCall () ")
Post your complete exit-routine code. <<< if i guess right, there should be the error.

That way more people can help and we do not need to guess whats wrong.

OptimalDesigns

  • Supporting Member
  • Joined in 2018
  • **
  • Posts: 70
  • (retired) Mathematical Engineer
    • View Profile
    • Calculus (level) Problem Solving; Examples & Compiler
    • Read more about this member.
    • Donate to Member
Yes, I forgot the declare stuff...

Private Declare Sub PSDcalc_for Lib "PSDcalc_for.dll" (ByVal fileNam As String, ByRef x_array As Single, _
  ByRef spectrum As Single, nptsZ As Integer, npointsZ As Integer, _
  t_startZ As Single, t_finalZ As Single, zeroFillZ As Single, sig2Z As Single, _
  nPoles As Integer, nZeros As Integer, M_eqs As Integer, M_lags As Integer, _
  Mode As Integer, L_pts As Integer, ByVal str_len As Long)
ooo

Public Sub exitProgram()
  ooo
' no longer have this code ...      Call EndProcess("PSDcalc_for.dll")
      If EndDLL("PSDcalc_for.dll") Then MsgBox "It worked!"

A problem is in the EndDLL("PSDcalc_for.dll") stmt.  EndDLL argument should be EndDLL(DllReturnValue As Long) ... that's a problem for sure.  What should be passed to EndDLL ... DllReturnValue As Long?

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • default avatar
  • Posts: 11,190
    • View Profile
    • Donate to Member
The parameter it's asking for is a Windows handle. 

But beyond that, there's something intrinsically wrong with this, I think.  Where did you get that EndDLL function from?  It seems to me that you're mixing ideas in calling the Fortran DLL from VB, and though you have it working, it's really not being called as intended, therefore your results could be suspect, as your problem coming out of the method point towards memory access errors.

Just ideas- I'm shooting very much in the dark here with only partial code to work from; it appears that your method, if it's defined as above, is not defined as _stdcall.  Check that first link I put in there- the instructions are for Fortran90, i.e.

If you are using CVF, then just add the following to the declaration of
mydllsub:
!DEC$ATTRIBUTES STDCALL:: mydllsub
!DEC$ATTRIBUTES DLLEXPORT:: mydllsub
!DEC$ATTRIBUTES ALIAS: 'mydllsub'::mydllsub
!DEC$ATTRIBUTES REFERENCE:: myarray,n,m

Then remove that EndDLL function and try it- that would be my final suggestion.

KodeZwerg

  • Honorary Member
  • Joined in 2018
  • **
  • Posts: 718
    • View Profile
    • Donate to Member
Other things that i do not understand fully yet:
If EndDLL("PSDcalc_for.dll") Then MsgBox "It worked!"
Translated in my world this would mean: If "something is TRUE" then "show Text"
BUT "EndDLL" is defined
Public Function EndDLL(DllReturnValue As Long) As Boolean
wich contain
hInst = DllReturnValue

Heres my problem:
You call EndDLL with a "String" but EndDLL wants "Long" as input.... VB or your Text is very confusing me :)

And yeah, comment that "EndDLL" out of Exit-Code.