Announcement

Collapse

New Sub-Forum

In an effort to help make sure there are appropriate categories for topics of discussion that are happening, there is now a sub-forum for databases and database programming under Special Interest groups. Please direct questions, etc., about this topic to that sub-forum moving forward. Thank you.
See more
See less

DLL will not terminate

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DLL will not terminate

    Hello,

    I wrote some functions und put them in a DLL. Now I want to call one exportet function from MS-Excel (VBA). The function runs fine, but after ending the function, the DLL do not terminate. The programicon remains in the taskbar and if I call the function again from Excel, some internal counters, which normally are unset and zero, start from the last positions.
    It seems, the ddl remains internally in memory.

    If I call the DLL from another PB-Program, all works correctly.

    Here some code.

    In the dll:
    Code:
    FUNCTION LIBMAIN (BYVAL hInstance   AS LONG, _
                      BYVAL fwdReason   AS LONG, _
                      BYVAL lpvReserved AS LONG) AS LONG
    
        SELECT CASE fwdReason
    
        CASE %DLL_PROCESS_ATTACH
            FUNCTION = 1
    
        CASE %DLL_PROCESS_DETACH
            FUNCTION = 1
    
        CASE %DLL_THREAD_ATTACH
            FUNCTION = 1
    
        CASE %DLL_THREAD_DETACH
            FUNCTION = 1
        END SELECT
    
    END FUNCTION
    
    
    FUNCTION Hauptprogramm ALIAS "Hauptprogramm" (Options AS STRING) EXPORT AS LONG 
    ...... code goes here

    In the calling PB-program:
    Code:
    #COMPILE EXE
    
    #INCLUDE "C:\PBWIN80\WINAPI\WIN32API.INC"
    
    FUNCTION PBMAIN () AS LONG
     DIM Parm    AS STRING
     DIM hLib     AS LONG
     DIM pAddr   AS DWORD
     Parm = COMMAND$
     hLib = LoadLibrary( "PIV_Create.dll")
     pAddr=GetProcAddress(BYVAL hLib, "Hauptprogramm")
     CALL DWORD pAddr BDECL (Parm)
     freeLibrary hLib
    
    END FUNCTION 
    another version with "DECLARE Program in DLL" like the VBA-example works also.
    In the Excel VBA-program:
    Code:
    Declare Function Hauptprogramm Lib "C:\PIV_ADD\PIV_Create.DLL" (Options As String) As Long
    
    Sub PiVTest()
     Call Hauptprogramm("MyParameter")
    End Sub
    Can someone help me?

    excuse my bad english!
    greets KHV

  • #2
    The function runs fine, but after ending the function, the DLL do not terminate.
    Why should it? The DLL will be unloaded after Excel is terminated...
    Regards,
    Peter

    Comment


    • #3
      Peter is right. The Dll will be unloaded from memory when Excel Terminates.

      But for example, if you have the Dll loaded in Excel, and then PB, the Dll will unload from Excel when it terminates, but will remain loaded in PB until it terminates.
      Engineer's Motto: If it aint broke take it apart and fix it

      "If at 1st you don't succeed... call it version 1.0"

      "Half of Programming is coding"....."The other 90% is DEBUGGING"

      "Document my code????" .... "WHYYY??? do you think they call it CODE? "

      Comment


      • #4
        Code:
        FUNCTION Hauptprogramm ALIAS "Hauptprogramm" (Options AS STRING) EXPORT AS LONG 
        ...... code goes here
        Um, what code? If this is launching (e.g., SHELL, ShellExecute[Ex]) another process - which is not terminated - then that process keeps running and you should expect to see that program's icon in the task bar.

        Just some semantics: "DLL [file]s" do not terminate or end. A DLL file is linked to a process (an exe program) via "LoadLibrary()" and is unlinked by that process when it calls FreeLibrary(). Other processes - e.g. a SHELLed process - may link the same DLL file .. which is the whole idea behind dynamic link libraries: common code may reside in one place.
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Just another thought.... perhaps the Excel function you want to draw upon has a COM interface? If so, then you could control Excel starting and ending as required... and for that matter, you could leave it invisible whilst it is "doing its thing."

          (I could not find a "Code goes Here" method in my Excel reference)
          Michael Mattias
          Tal Systems Inc. (retired)
          Racine WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Hi Karl,
            Meine Deutsche ist nicht so gute myself, so I know how you feel about your English, but it is fine.

            Just out of "Kowinki-dink" I recognized some of your pseudo-code and wondered if you are working on a Particle image velocimetry (PIV) type of application? (Just curious)

            Since VBA is really nothing more than VB (plus or minus some keywords, and minor changes in how to program), I thought maybe I or some others that are from the age of old VB may be able to help.

            If you can post a few actual functions from your code, I am sure we can point out a few things.

            Engineer's Motto: If it aint broke take it apart and fix it

            "If at 1st you don't succeed... call it version 1.0"

            "Half of Programming is coding"....."The other 90% is DEBUGGING"

            "Document my code????" .... "WHYYY??? do you think they call it CODE? "

            Comment


            • #7
              Thanks to all
              for your answers.

              You are right. The DLL is terminated or better (@Michael) unlinked.

              While running the function I show the progress in a progressbar with an abort-button. Clicking on this to abort the executing does not work right. The screen is not updatet until the hole process is complete, then it's drawn and all seems to be ok. But after starting again, the progressbar starts with the old values, so, if it (the progressbar) has not terminated.

              This is only, if I call it from Excel in a DLL.

              My program have to do a lot of work, only the result is to be presented in MS-Excel. And I want, that the User only has contact with Excel, so I want to start the process from an Excelbutton.

              Here the ways to realize my wishes:
              All done by Excel in VBA ->works, but to slow
              realized by PB and COM ->works, but to slow
              done by PB-Exefile, called by Excel ->works
              done by PB-DLLfile, called by PB-Exefile ->works
              done by PB-DLLfile, called by Excel ->works bad with the above effects.

              I do not understand, what is different. It is the same code.

              @Michael: With "code goes here" I wanted only to say, that there is my code. To much to post here.

              @Cliff: PIV is german shotword and stands for "Plan-Ist-Vergleich". It is a costreport used by the controlling........


              Mybe the mistake is to be found here. I will look.
              Code:
              CALLBACK FUNCTION PBarDlgProc () AS LONG
                  LOCAL i      AS LONG
                  LOCAL lMax   AS LONG
                  STATIC Abort AS LONG
                  STATIC Prozent AS STRING
              
                  SELECT CASE CBMSG
                  CASE %WM_INITDIALOG
                      CONTROL SEND CBHNDL, %ID_PROGRESS, %PBM_SETRANGE, 0, MAKLNG(0, 100)
              
                  CASE %WM_COMMAND
                      SELECT CASE CBCTL
              
                      CASE %ID_NewText
                           Position& = geleseneByte/TotalByte*100
                           CONTROL SEND CBHNDL,     %ID_PROGRESS, %PBM_SETPOS, Position&, 0
                           CONTROL SET TEXT CBHNDL, %ID_PROGRLBL,  Prozesstext1
                           CONTROL SET TEXT CBHNDL, %ID_PROGRLBL2, Prozesstext2
                           T$ = FORMAT$(geleseneByte/TotalByte*100,"###.#")
                           REPLACE "." WITH "," IN T$
                           T$ = T$ & "% bearbeitet!"
                           IF T$ <> Prozent THEN
                             CONTROL SET TEXT CBHNDL, %ID_PROGRLBL2+1, T$
                             Prozent = T$
                           END IF
                           DIALOG REDRAW CBHNDL
                           DIALOG DOEVENTS
              
                      CASE %ID_Abbruch
                           DIALOG END CBHNDL, 0
                           Abbruch = 1
              
                      CASE %IDCANCEL
                          IF CBCTLMSG = %BN_CLICKED THEN
                              IF MSGBOX("Möchten Sie wirklich abbrechen?", _
                                        %MB_YESNO OR %MB_ICONQUESTION OR %MB_TASKMODAL, _
                                        "Abort?") = %IDYES THEN Abbruch = 1 : DIALOG END CBHNDL, 0
              
                          END IF
                      END SELECT
              
              
                  CASE %WM_SYSCOLORCHANGE
                      CONTROL SEND CBHNDL, %ID_PROGRESS, CBMSG, CBWPARAM, CBLPARAM
              
                  END SELECT
              
              END FUNCTION
              greets KHV

              Comment


              • #8
                Clicking on this to abort the executing does not work right. The screen is not updatet until the hole process is complete, then it's drawn and all seems to be ok
                That's because you are not using multiple threads of execution. When you call your external function or program, you are processing a message.. which means no more messages (eg "ABORT") in that thread's context are going to be processed until the current message processing is completed.

                Recent demo:
                GUI + Worker Thread + Abort Demo

                If all you are interested in is a progress bar which is updated smoothly, an older demo:
                Progress Bar Dialog for PB/CC programs October 24, 2002

                (Don't worry that it was created for PB/CC, it's easily usable in PB/WIN)

                MCM
                Last edited by Michael Mattias; 1 Dec 2007, 10:04 AM. Reason: Corrected my failure to use 'thread' as an adjective or at least part of an integrated multi-word noun.
                Michael Mattias
                Tal Systems Inc. (retired)
                Racine WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  done by PB-Exefile, called by Excel ->works
                  done by PB-DLLfile, called by Excel ->works bad with the above effects.

                  I do not understand, what is different. It is the same code.
                  An executable is a stand-alone program, that does it's job and then stops. (Because all is done and there isn't anymore to do)

                  A dll is a LIBRARY, that Excel gets access to. The requested function is executed by Excel, but there is no reason for Excel to unload the dll. Normally more functions in the same dll can be executed, and it would be very time consuming to load/unload the dll on every call...
                  (Normally a DLL doesn't hold only a single function...)
                  Regards,
                  Peter

                  Comment


                  • #10
                    Let me know if the below diagrams make more sense. (and yes MCM, I know not totally correct, but I think this "Hand-Grenade" is close enough to target )

                    (Arrows = Communications, Lines = Who is "OWNED" by who)
                    Code:
                    I.) All done by Excel in VBA ->works, but to slow
                    
                    _________
                    |       |
                    | Excel |   (Process)
                    |       |
                    |_______|
                         |
                         |----------------------------
                         |               |           |
                    _____|_______     ___|___     ___|___
                    |           |     |     |     |     |
                    | Worksheet |<--->| VBA |<--->| COM |
                    |           |     |     |     |     |
                    |___________|     |_____|     |_____|
                    
                    M$ Overhead slows things down, but the same could be said for realized by PB and COM(M$ Overhead) ->works, but to slow
                    Excel "Owns" the worksheet, VBA, and the COM, and each peice only "Communicates" with the other peice.
                    To close all, Excel itself must close, not just the worksheet
                    
                    
                    
                    II.) Done by PB-Exefile, called by Excel ->works
                    _________
                    |       |
                    | Excel |   (Process)
                    |       |
                    |_______|
                         |
                         |----------------
                         |               |
                    _____|_______     ___|___     __________
                    |           |     |     |     |        |
                    | Worksheet |<--->| VBA |<--->| PB EXE |   (Process)
                    |           |     |     |     |        |
                    |___________|     |_____|     |________|
                    
                    PB EXE is a seperate process and only "Communicates" with the VBA, but is not owned by it
                    PB EXE must be closed seperately from closing Excel
                    
                    
                    
                    III.) Done by PB-DLLfile, called by PB-Exefile ->works
                    _________
                    |       |
                    | PB    |   (Process)
                    |       |
                    |_______|
                         |
                         |
                         |
                    _____|_______
                    |           |
                    | Dll       |
                    |           |
                    |___________|
                    
                    Dll is owned by the PB process, and therefore "closes" when the owning process closes
                    
                    
                    
                    
                    IV.) Done by PB-DLLfile, called by Excel ->works bad with the above effects. 
                    _________
                    |       |
                    | Excel |   (Process)
                    |       |
                    |_______|
                         |
                         |----------------------------
                         |               |           |
                    _____|_______     ___|___     ___|___
                    |           |     |     |     |     |
                    | Worksheet |<--->| VBA |<--->| DLL |
                    |           |     |     |     |     |
                    |___________|     |_____|     |_____|
                    
                    DLL only "Communicates" with VBA and Worksheet, but is not "OWNED" by either of them
                    DLL is "OWNED" by Excel, and will not be released until Excel itself is closed.
                    Which is why your Variables remain the same, and the "Slowness" (although much faster without M$ overhead)
                    Is because each call to a function in your DLL does not return until the function is finished
                    
                    Now if you thread your functions, then the diagram becomes more like
                    _________
                    |       |
                    | Excel |   (Process)
                    |       |
                    |_______|
                         |
                         |----------------xxxxxxxxxxxx
                         |               |           x
                    _____|_______     ___|___     ___x___
                    |           |     |     |     |     |
                    | Worksheet |<--->| VBA |<xxx>| DLL |
                    |           |     |     |     |     |
                    |___________|     |_____|     |_____|
                    
                    Although still "OWNED" by Excel, the functions themselves return immediately so the VBA can continue on
                    while the function is running in the DLL. Then when it is done, you can check its results and do what you need with it
                    (Speeding things up tremendously depending on what you are doing)
                    Engineer's Motto: If it aint broke take it apart and fix it

                    "If at 1st you don't succeed... call it version 1.0"

                    "Half of Programming is coding"....."The other 90% is DEBUGGING"

                    "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                    Comment


                    • #11
                      @Cliff, thank you for your interesting graphics.

                      In future I will try to program more with threads. A new field for me. Until yet I did not program with threads.

                      @MCM, thanks too. I 'll check your example soon.

                      I'll have to go out with my dogs now, they are 'am quängeln' :-)
                      greets KHV

                      Comment


                      • #12
                        Well, get used to seeing that linked demo. It's something I should have done years ago.

                        "How can I get my screen to update and/or implement an abort when I need to do something time-consuming?" has been a very common question on these forums for a very long time.

                        MCM
                        Michael Mattias
                        Tal Systems Inc. (retired)
                        Racine WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment

                        Working...
                        X