Announcement

Collapse
No announcement yet.

Unloading DLLs

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

  • Unloading DLLs

    How does one go about explicitly unloading DLLs from PB apps?

    ------------------
    Walt Decker

  • #2
    Check out FreeLibrary() (and LoadLibrary()) in WIN32.HLP... of course, you'll need the handle of the library first, which means it is likely you explicitly loaded the target library to begin with.

    Explicitly loading and unloading DLL's at run-time is known as run-time linking (as opposed to load-time or implicit linking which causes Windows to load all DLL's that your app is dependent upon before your app is actually executed).

    The concept behind DLL's is that only one copy is loaded at any one time (although there are exceptions to this general rule) and this single copy is mapped into the address space of each process that uses the DLL. Essentially, FreeLibrary() reduces the instance count of the DLL, and the DLL is actually only unloaded from memory when the instance count reaches zero, but it will be unmapped from your process address space during the call to FreeLibrary().

    What specifically do you wish to achieve?

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      Lance --
      I have no idea, what Walt needs, but I am interesting, how to unload a DLL, mentioned in LIB.

      ------------------
      E-MAIL: [email protected]

      Comment


      • #4
        but I am interesting, how to unload a DLL, mentioned in LIB.
        LIB? You have lost me here... are you talking about implicitly linked DLL's?




        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          Declare Prog1 Lib "a.Dll" Alias "....."

          How to unload a.dll ? (in VB it's possible)

          ------------------
          E-MAIL: [email protected]

          Comment


          • #6
            As I understand it, VB explicitly links DLL's with run-time linking... Although I'm not a VB programmer, I seem to recall that is why the DLL declarations are usually placed in a "module" (please correct me if I'm wrong!)

            For the lurkers here: If you need this type of functionality, switch to run-time linking and use GetProcAddress()/CALL DWORD to call the required DLL functions. For example code, search the BBS for "GetProcAddress".



            ------------------
            Lance
            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            Lance
            mailto:[email protected]

            Comment


            • #7
              In my understanding VB does GetModuleHandle + GetProcAddr in any case.
              That's why it's possible to release.

              PB loads DLL (from LIB) in prologue and doesn't give a possibility to release.

              LIB are more comfortable comparing with LoadLibrary ... Call Dword.

              Probably, in future releases should be a possibility of "delayed" loading:
              sometimes, appears a wish to reload a non-reenterable DLL; or
              DLL simply doesn't exist, but program is able to process such situation
              (classic sample - RICHED20.DLL).




              ------------------
              E-MAIL: [email protected]

              Comment


              • #8
                As I understand it, VB explicitly links DLL's with run-time linking... Although I'm not a VB programmer, I seem to recall that is why the DLL declarations are usually placed in a "module" (please correct me if I'm wrong!)
                Um, you are correct, but so does PowerBASIC. And "run-time linking" is kinda the whole idea of a "Dynamic Link Library."

                All LoadLibary/GetProcAddress/FreeLibrary et al do is change when the procedures in the DLL are linked - at startup or on demand - and allow dynamic "unlink and unload."

                As far as unloading a DLL loaded automatically at program startup, one might try using the GetModuleHandle API call, subject to this casution from the SDK:

                Note that the reference count is used in FreeLibrary to determine whether to unmap the function from the address space of the process. For this reason, use care when using a handle returned by GetModuleHandle in a call to FreeLibrary because doing so can cause a dynamic-link library (DLL) module to be unmapped prematurely.
                MCM

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

                Comment


                • #9
                  Thank's for the info, Lance. What I'm trying to achieve is a reduction in memory. Escentially, the app I have uses several procedures only once during startup. These procedures have to do with the validity of an *.ini file. Once the validity is checked, all other instances of the app use the *.ini file and not the *.ini check procedures. Thus, other instances of the app do not require them.



                  ------------------
                  Walt Decker

                  Comment


                  • #10
                    Walter, yes, your requirement should be fairly easy to implement... just create the INI code stuff in a DLL and explicitly load the DLL with LoadLibrary(), get the address of the target (exported) Sub/Function in the DLL with GetProcAddress(), call the code with CALL DWORD, and free the library with FreeLibrary().

                    Originally posted by Michael Mattias:
                    Um, you are correct, but so does PowerBASIC. And "run-time linking" is kinda the whole idea of a "Dynamic Link Library."
                    You appear to be confusing two terminologies, Michael. Run-time linking is performed by explicitly loading a DLL with LoadLibrary() from within the running code, whereas you refer to the process of load-time linking which causes DLL's to be implicitly loaded *before* the main app starts running, and is done automatically by Windows.

                    This is the major difference between the two methods of linking... implicitly referenced DLL's are loaded automatically with load-time linking.

                    My understanding of VB is that it does explicit run-time linking. Since a VB app can still run if a "module-referenced" DLL fails to load, is *has* to be using run-time linking.

                    If an app implicitly (at load-time) links to a missing DLL (or the DLL's LibMain() function returns zero), then the whole app will fail to execute. Clearly VB does not use this technique, but in PB you have to explicitly load the DLL yourself to gain the same "functionality" (for lack of a better term).




                    ------------------
                    Lance
                    PowerBASIC Support
                    mailto:[email protected][email protected]</A>
                    Lance
                    mailto:[email protected]

                    Comment


                    • #11
                      I had not thought about the difference between "run time" and "load-time" linking, but thanks to your tip, I looked it up.

                      I am kinda in the wrong mindset to be discerning, as I am working on an article about, "Use DLLs Because Static Libraries are For Wimps" and I have only been looking at "compile time" and "any other time."

                      (That working title probably won't survive).

                      MCM

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

                      Comment


                      • #12
                        Guys,

                        You really have only 2 choices with dynamic link libraries, you either
                        link to them at startup or you DYNAMICALLY link them at you coded choice
                        at runtime.

                        The compiler will handle the startup linking for you if you make the
                        correct declarations and it will load them at startup and unload them on
                        exit.

                        With Walt's original question for a PowerBASIC application, the method Lance
                        suggested is the best way to do the job, LoadLibrary(), GetProcAddress()
                        and FreeLibrary().

                        Dynamic linking in its original sense meant being able to link to a pre
                        built module of binary code at the time of the programmers choice, run the
                        code then unload it when it is no longer needed. This is the most efficient
                        way to use DLLs in that you control what the application's memory usage is
                        as it is running where startup linking cannot do this.

                        For a programmer who needs to load a very large DLLs on an occasional basis,
                        dynamic linking solves the memory usage problems in that you only load what
                        is needed. The example is if a machine had nominally 10 meg free memory
                        after loading the operating system, the application loads 2 meg and there
                        is about 8 meg free.

                        Linking at startup says at the most the total memory usage of the DLLs can be
                        about 8 meg where if the programmer writes the program to load any of a
                        number of 5 meg DLLs one at a time, there is no effective limit on how many
                        DLLs can be called.

                        The logic is very simple and it works well if you can be bothered writing the
                        extra code to do it. LoadLibrary() gets the handle of the DLL and
                        GetProcAddress() gets the address of the function being called from within
                        the DLL.

                        You can either use CALL DWORD or you can call it directly in assembler, both
                        work well. This option is considerably more flexible than delayed loading in
                        the VC++ sense in that you can multiply load and unload the DLL on a needs
                        basis.

                        Regards,

                        [email protected]

                        ------------------
                        hutch at movsd dot com
                        The MASM Forum

                        www.masm32.com

                        Comment

                        Working...
                        X