Announcement

Collapse
No announcement yet.

Stupid Loadlibrary questions

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

  • Stupid Loadlibrary questions

    Often I hear "Stupid" questions regarding programming (and yes I make quite a few myself)

    That is, until I take a moment to remember "The only stupid question, is the one not NOT asked", so I will just ask and admit my stupidity

    When it comes to loadlibrary, I see many schools of thought, and just wondered which is correct? or if just a matter of choice? (hoping I do not spark a debate, but had to ask)

    In my mind (from what I understand from the docs, and the forums) Loadlibrary may or may not follow one or more of the following:

    Scenario 1: - Local to the function you are currently using
    • Loadlibrary
    • Get the address to function you need
    • Use the address
    • Safety checks if the function exists.....(Or do I need this? or is it just my own check to be sure?)
    • FreeLibrary

    That one pretty much ensures I got what I need, but if the 1st call to dll then isn't the dll mapped into my process until my process ends?

    Scenario 2: - Local to the process
    • Loadlibrary
    • Get each of the addresses to function(s) you need and store in global variables for use later
    • Use the addresses
    • Safety checks if the function exists.....(Or do I need this? or is it just my own check to be sure?)
    • FreeLibrary at the end of my process

    That one pretty much ensures I got what I need, but is it possible that what I read at the begginning did not change somewhere and at the end is now a new address?

    Scenario 3: - Local to the process (sorta)
    • Loadlibrary
    • Get the addresses to function you need and store in global variables?
    • FreeLibrary
    • Use the addresses
    • Safety checks if the function exists.....(Or do I need this? or is it just my own check to be sure?)

    That one pretty much works, but since I load and free, are the addresses still good if I load once and free, only because still in the same process? Or am I asking for even more trouble with this one?

    I get the "Scope" concept, but with the word "Scope", just what exactly is happening? is it the scope of the function that I look things up? or the scope that I mapped a dll into my process?, or does the scope get lost when I free?, or not really lost till my process ends?

    must be confusing but then again now you know why I asked
    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? "

  • #2
    Okay, another stupid question.

    Why are messing around with addresses?
    Roy Cline

    Comment


    • #3
      Might be dynamic binding to the DLLs. I do this for plug-in modules I have for my main EXE on some applications.

      A more simplisitic look at your scenario's may work better...

      you should only need to check for errors on loadlibrary and getprocaddress to verify you have a valid DLL and function.

      As for when to FREELIBRARY in relation to the LOADLIBRARY it is completely based on your applications needs.
      • In one of my applications I LOADLIBRARY, call function, FREELIBRARY all in one function as it enumerates through a substantial number of DLL's. I don't want or need to manage all DLLs and the actual number of DLL's can change on the fly while the application is running. I just enumerate DLL's, then loop through a load -> use -> free.
      • In another application I do a LOADLIBRARY in the PBMAIN and FREELIBRARY when the application closes.
      In all cases the FREELIBRARY happens after you are done using the function(s) in that DLL, not before. So your scenario #3 is a bust.
      Last edited by George Bleck; 17 Oct 2007, 09:13 AM.
      <b>George W. Bleck</b>
      <img src='http://www.blecktech.com/myemail.gif'>

      Comment


      • #4
        Well, I have looked and read and must admit I don't understand: so be it.
        Roy Cline

        Comment


        • #5
          Roy, "typically" you just declare the DLL function using:
          DECLARE FUNCTION LegalName LIB "filename.DLL" ALIAS "Illegal$Name"(variable list)
          And you just call the function like normal in your application. Simple, neat, easy.

          BUT...what if you write an application that can allow plugin's to do certain things. Obviously the application does not previously know of the existance of these plugin's therefore you cannot pre-declare the functions. So how do you handle this case? Using dynamic binding.

          Using Winamp as an example... each plugin has a DLL that you install into the Winamp plugin directory. Winamp will search for all the DLL's in the plugin sub-directory, and will call the plugins using a pre-arranged "entry function". An entry function is a function that all plugin DLL's in the directory would have in common. Think of it as a protocol...a common way of communicating between two points. The rest of each DLL can be completely different and do different things, but all the plugins require the common entry function to at least start something off.

          I hope that helps a little.
          Last edited by George Bleck; 17 Oct 2007, 09:11 AM.
          <b>George W. Bleck</b>
          <img src='http://www.blecktech.com/myemail.gif'>

          Comment


          • #6
            The Api documentation is pretty clear on this point. From FreeLibrary()...

            Remarks

            Each process maintains a reference count for each loaded library module. This reference count is incremented each time LoadLibrary is called and is decremented each time FreeLibrary is called. A DLL module loaded at process initialization due to load-time dynamic linking has a reference count of one. This count is incremented if the same module is loaded by a call to LoadLibrary.

            Before unmapping a library module, the system enables the DLL to detach from the process by calling the DLL's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the DLL an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.

            or...

            Run-Time Dynamic Linking

            When the application calls the LoadLibrary or LoadLibraryEx functions, the system attempts to locate the DLL using the same search sequence used in load-time dynamic linking (see Load-Time Dynamic Linking). If the search succeeds, the system maps the DLL module into the virtual address space of the process and increments the reference count. If the call to LoadLibrary or LoadLibraryEx specifies a DLL whose code is already mapped into the virtual address space of the calling process, the function simply returns a handle to the DLL and increments the DLL reference count. Note that two DLLs that have the same base filename and extension but are found in different directories are not considered to be the same DLL.

            The system calls the entry-point function in the context of the thread that called LoadLibrary or LoadLibraryEx. The entry-point function is not called if the DLL was already loaded by the process through a call to LoadLibrary or LoadLibraryEx with no corresponding call to the FreeLibrary function.

            If the system cannot find the DLL or if the entry-point function returns FALSE, LoadLibrary or LoadLibraryEx returns NULL. If LoadLibrary or LoadLibraryEx succeeds, it returns a handle to the DLL module. The process can use this handle to identify the DLL in a call to the GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread function.

            The GetModuleHandle function returns a handle used in GetProcAddress, FreeLibrary, or FreeLibraryAndExitThread. The GetModuleHandle function succeeds only if the DLL module is already mapped into the address space of the process by load-time linking or by a previous call to LoadLibrary or LoadLibraryEx. Unlike LoadLibrary or LoadLibraryEx, GetModuleHandle does not increment the module reference count. The GetModuleFileName function retrieves the full path of the module associated with a handle returned by GetModuleHandle, LoadLibrary, or LoadLibraryEx.

            The process can use GetProcAddress to get the address of an exported function in the DLL using a DLL module handle returned by either LoadLibrary, LoadLibraryEx, or GetModuleHandle.

            When the DLL module is no longer needed, the process can call FreeLibrary or FreeLibraryAndExitThread. These functions decrement the module reference count and unmap the DLL code from the virtual address space of the process if the reference count is zero.

            Run-time dynamic linking enables the process to continue running even if a DLL is not available. The process can then use an alternate method to accomplish its objective. For example, if a process is unable to locate one DLL, it can try to use another, or it can notify the user of an error. If the user can provide the full path of the missing DLL, the process can use this information to load the DLL even though it is not in the normal search path. This situation contrasts with load-time linking, in which the system simply terminates the process if it cannot find the DLL.

            I can't imagine why one would load a library explicitely, get the address of a procedure which you just mapped into your address space, then release the library and call the function. What if Windows indeed did release the library and the memory is now being used for something else in your process? I wouldn't expect that to work consistently without problems.
            Fred
            "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

            Comment


            • #7
              >I can't imagine why one would load a library explicitely
              Code:
              IF DIR$("SomeDll.dll" ) => ""  then    ' found on target system 
                LoadLibrary
                GetProc Address
                CALL DWORD
                FreeLibrary
              ELSE
                MSGBOX "This feature not installed on this system"
              END IF
              If DLL file not found on target system, use of "DECLARE.. LIB "Some.DLL" .. " syntax will result in Load Failure at execution time with message from Windows "cannot locate application or one of its components."

              [ADDED]

              Yes, you qualified that statement; I provided this for the benefit of those who might not understand why you'd want to do dynamic loading in the first place.

              That said, given the general principle of Thou Shalt Release (free, deallocate, close) What Thou Wouldst Obtain (Get, Allocate, Open), I've always believed that with rare exceptions you get more maintainable - and readily reuseable - code by always releasing in the same procedure in which you obtain.

              It is a 'general' principle, for example, that you never leave a disk file open whilst waiting for user input. I just apply that principle to essentially anything I "obtain" and "release" it as soon as I'm done processing the current request.


              MCM
              Last edited by Michael Mattias; 17 Oct 2007, 11:38 AM. Reason: Added stuff
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                Mike, I think the "Can't imagine" refers to "then release the library and call the function"
                <b>George W. Bleck</b>
                <img src='http://www.blecktech.com/myemail.gif'>

                Comment


                • #9
                  I figured scenario 3 only works because my process has not tried to reclaim space that was using resources and later on was sitting idle because I did the "Freelibrary", so its sheer luck that I can still use that "address" and make the function work. (Well not sheer luck...but only viable until Windows reclaims that space)

                  If thats the case, then out of sheer curiosity (probably only M$ could answer), is if calling a function location that I freed, and has not been reclaimed, in turn re-maps the dll back into my process?
                  (just a theoretical thought)
                  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


                  • #10
                    You could try it out and see easy enough. Make a procedure with several loads and releases and see if you get the same address of some specific symbol in the dll every time. To make it more realistic I'd intersperse the loads/releases with some dummy code to shake things up a bit, like maybe some megabyte memory allocations/de-allocations. And of course as you probably know it might give different results on different computers, and so on.

                    One thing though, if you're doing loads/function calls/releases all within one procedure (or procedures called from one procedure), I can't see any reason not to make all the hDlls, ptrFns local. Why bother with Globals if the scope of the activity is one procedure and the duration of the activity is just the life of that procedure?
                    Fred
                    "fharris"+Chr$(64)+"evenlink"+Chr$(46)+"com"

                    Comment


                    • #11
                      is [] calling a function location that I freed, and has not been reclaimed, in turn re-maps the dll back into my process?
                      No.

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

                      Comment


                      • #12
                        Thank you MCM...I thought that was the case, but no way to test (to my knowledge) until (IF POSSIBLE) that I could force a freedom and then reclaim from code like Windows does

                        (this would be an EXTREME test, but one I would like to do someday so I can totally understand "How things work under the hood" what most people take for granted)
                        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

                        Working...
                        X