Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / June 2009



Tip: Looking for answers? Try searching our database.

Does a standard DLL stay in memory?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Greg Lovern - 15 Jun 2009 19:50 GMT
In VB6, if I declare a function in a standard DLL with
"Declare Function" (etc.), and then in the code make a call to that
function in the standard DLL, does the DLL stay in memory until the VB
application is closed?

Or is the standard DLL unloaded after each call to it?

Thanks,

Greg
Nobody - 15 Jun 2009 20:05 GMT
> In VB6, if I declare a function in a standard DLL with
> "Declare Function" (etc.), and then in the code make a call to that
> function in the standard DLL, does the DLL stay in memory until the VB
> application is closed?
>
> Or is the standard DLL unloaded after each call to it?

It stays loaded. However, I think you can control when its loaded and
unloaded by specifically calling LoadLibrary() before using any function in
it, and when you no longer need it, call FreeLibrary().
Kevin Provance - 15 Jun 2009 22:35 GMT
| It stays loaded. However, I think you can control when its loaded and
| unloaded by specifically calling LoadLibrary() before using any function in
| it, and when you no longer need it, call FreeLibrary().

That's an interesting approach.

If I use LoadLibrary to load a standard DLL, would a standard declaration
use that loaded instance or load it's own?  What if that DLL injects itself
into a different process?  Would FreeLibrary unload that as well?  I was
under the working assumption it did not until the process it was loaded in
closed.
Karl E. Peterson - 15 Jun 2009 22:52 GMT
>| It stays loaded. However, I think you can control when its loaded and
>| unloaded by specifically calling LoadLibrary() before using any function in
[quoted text clipped - 4 lines]
> If I use LoadLibrary to load a standard DLL, would a standard declaration
> use that loaded instance or load it's own?

That module will only load once into a given process.

> What if that DLL injects itself into a different process?

That'd be a different process, and those are distinct in Win32.

> Would FreeLibrary unload that as well?

No way.

> I was under the working assumption it did not until the process it was
> loaded in closed.

That's how VB was designed.  It'll call LoadLibrary if it doesn't find the module
needed when needed, then call FreeLibrary against all on shutdown.  This method
would sidestep that.  You could test it easily enough, with EnumProcessModules.  But
if you don't explicitly call it outside a Load/FreeLibrary pair, it shouldn't load
on its own, so therefore it can't unload on its own either.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Nobody - 16 Jun 2009 10:33 GMT
>| It stays loaded. However, I think you can control when its loaded and
> | unloaded by specifically calling LoadLibrary() before using any function
[quoted text clipped - 9 lines]
> under the working assumption it did not until the process it was loaded in
> closed.

After some research the approach that I described won't work. However, an
alternative is to enumerate the modules by using toolhelp functions, such as
Module32First/Module32Next, or EnumProcessModules, and call FreeLibrary on
the DLL handle. However, if VB keeps internal information about the DLL, you
may get unpredictable behavior if you called any function in that DLL after
calling FreeLibrary.

When LoadLibrary is called, the DLL is loaded if not loaded already and a
reference counter for the process is incremented, and when FreeLibrary is
called, it's decremented. Once the reference count for the process reaches
0, the DLL is unloaded from the address space of that process.
Karl E. Peterson - 16 Jun 2009 19:48 GMT
> After some research the approach that I described won't work.

Huh?  It's certainly "worked" for me.  Different definitions of "work"?
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Nobody - 16 Jun 2009 21:14 GMT
>> After some research the approach that I described won't work.
>
> Huh?  It's certainly "worked" for me.  Different definitions of "work"?

Try this sample: Add two command buttons, the first loads the library and
call a function in it, and the other frees it. Use Process Explorer to see
loaded DLL's. In VB6+SP5 on XP+SP2, the DLL remains loaded in the process
even after calling FreeLibrary, which returns Success.

Output:

LoadLibrary returned 2115895296, LastDllError = 0
API function returned 1, LastDllError = 0
FreeLibrary returned 1, LastDllError = 0

' Form1 code

Option Explicit

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" ( _
   ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" ( _
   ByVal hLibModule As Long) As Long
Private Declare Sub OutputDebugString Lib "kernel32" Alias _
   "OutputDebugStringA" (ByVal lpOutputString As String)

Private Declare Function IsValidURL Lib "URLMON.dll" (ByVal pbc As Long, _
   ByVal szURL As String, ByVal dwReserved As Long) As Long

Private hLibModule As Long

Private Sub Command1_Click()
   Dim ret As Long

   hLibModule = LoadLibrary("URLMON.dll")
   OutputDebugString "LoadLibrary returned " & hLibModule & _
       ", LastDllError = " & Err.LastDllError
   ret = IsValidURL(0, "http://www.cnn.com", 0)
   OutputDebugString "API function returned " & ret & ", LastDllError = " _
       & Err.LastDllError
End Sub

Private Sub Command2_Click()
   Dim ret As Long

   ret = FreeLibrary(hLibModule)
   hLibModule = 0
   OutputDebugString "FreeLibrary returned " & ret & ", LastDllError = " _
       & Err.LastDllError
End Sub
Scott Seligman - 16 Jun 2009 22:05 GMT
>>> After some research the approach that I described won't work.
>>
[quoted text clipped - 4 lines]
>loaded DLL's. In VB6+SP5 on XP+SP2, the DLL remains loaded in the process
>even after calling FreeLibrary, which returns Success.

That's expected.  From MSDN for FreeLibrary:

] This function decrements the reference count of the loaded DLL module.
]
] When the reference count reaches zero, the module is unmapped from
] the address space of the calling process and the handle is no longer
] valid.

So, your call to FreeLibrary won't unload the DLL since the reference
count is presumably still 1 from VB's call to LoadLibrary. You might be
able to unload the DLL by having an unbalanced number of FreeLibrary
calls, but that's a hack at best, and will probably cause VB to blow up
if you call into the DLL again.

Signature

--------- Scott Seligman <scott at <firstname> and michelle dot net> ---------
  For of all sad words of tongue or pen, the saddest are these: 'It
  might have been.'
  -- John Greenleaf Whittier

Thorsten Albers - 16 Jun 2009 22:26 GMT
Nobody <nobody@nobody.com> schrieb im Beitrag
<#PDPI8r7JHA.1424@TK2MSFTNGP02.phx.gbl>...
> Try this sample: Add two command buttons, the first loads the library and

> call a function in it, and the other frees it. Use Process Explorer to see
> loaded DLL's. In VB6+SP5 on XP+SP2, the DLL remains loaded in the process

> even after calling FreeLibrary, which returns Success.

Of course VB has to do an internal call to LoadLibrary() in any case no
matter how often and/or where you have added that call in your code. VB
doesn't know anything about these 'manual' calls to LoadLibrary().

... = LoadLibrary(MyDLL)          ' Ref. count +1 -> 1
<VB internal: LoadLibrary(MyDLL)  ' Ref. count +1 -> 2
Call MyDLLFunction)
FreeLibrary(MyDLL)                ' Ref. count -1 -> 1

...

End of process requested
<VB internal: FreeLibrary>        ' Ref. count -1 -> 0

Signature

Thorsten Albers

albers (a) uni-freiburg.de

Karl E. Peterson - 16 Jun 2009 22:38 GMT
> Nobody <nobody@nobody.com> schrieb ...
>> Try this sample: Add two command buttons, the first loads the library and
[quoted text clipped - 17 lines]
> End of process requested
> <VB internal: FreeLibrary>        ' Ref. count -1 -> 0

That's the same conclusion I was arriving at.  So the real utility of LoadLibrary is
to call a function in a DLL that doesn't exist in the normal DLL search path (isn't
in a predictable pre-compile location).  I guess, to me, "worked" meant I was able
to A) call the function and B) not blow up. <g>

So, I wonder what would happen in a case such as that?  It doesn't fail, as it
normally would when it can't find an entry point or the DLL itself.  Does the 2nd
LoadLibrary (VB's) succeed because we already loaded it?  Hmmm...
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Thorsten Albers - 16 Jun 2009 23:34 GMT
Karl E. Peterson <karl@exmvps.org> schrieb im Beitrag
<eMKRdrs7JHA.1196@TK2MSFTNGP03.phx.gbl>...
> So the real utility of LoadLibrary is
> to call a function in a DLL that doesn't exist in the normal DLL search path (isn't
> in a predictable pre-compile location).

There are other situations where LoadLibrary() is usefull, e.g.:
- Test, if a library can be loaded at all (otherwise one would have to
catch the error thrown by VB when the call to one of its functions is done)
- Check, if the library holds a certain function (GetProcAddress())
etc.

> So, I wonder what would happen in a case such as that?  It doesn't fail, as it
> normally would when it can't find an entry point or the DLL itself.  Does the 2nd
> LoadLibrary (VB's) succeed because we already loaded it?  Hmmm...

Do you mean using LoadLibrary() and Declare ... for the same DLL with
different pathes? If so: On Windows with NT technology the two AFAIK would
be handled different because due to a different path they are not regarded
as two instances of the same DLL even if DLL 2 is just a copy of DLL 2. On
Windows 9x AFAIK both would be handled as two instances of the same DLL
because there only the file name matters, not the file path.

Signature

Thorsten Albers

albers (a) uni-freiburg.de

Karl E. Peterson - 16 Jun 2009 23:47 GMT
> Karl E. Peterson <karl@exmvps.org> schrieb ...
>> So the real utility of LoadLibrary is
[quoted text clipped - 4 lines]
> - Test, if a library can be loaded at all (otherwise one would have to
> catch the error thrown by VB when the call to one of its functions is done)

Yeah, good one, there.

> - Check, if the library holds a certain function (GetProcAddress())
> etc.

Definitely done that before.  eg, GetDiskFreeSpaceEx.

>> So, I wonder what would happen in a case such as that?  It doesn't fail, as it
>> normally would when it can't find an entry point or the DLL itself.  Does the 2nd
>> LoadLibrary (VB's) succeed because we already loaded it?  Hmmm...
>
> Do you mean using LoadLibrary() and Declare ... for the same DLL with
> different pathes?

Not exactly.  No path in the declare, but the DLL is off the standard LoadLibrary
search path.  So, you have to programatically find it, then do an explicit
LoadLibrary on it.  (eg, http://vb.mvps.org/samples/MultiOE/)  Hmmmm, now that I
look at that project again (hey, it's been five years! <g>), I guess I did do it a
bit differently there.  I actually just used LoadLibrary to make sure I'd found a
good DLL, and then ChDir'd into that DLLs file before making the first call to it.
That enabled VB's LoadLibrary to succeed, by bringing it into the search path.

> If so: On Windows with NT technology the two AFAIK would
> be handled different because due to a different path they are not regarded
> as two instances of the same DLL even if DLL 2 is just a copy of DLL 2. On
> Windows 9x AFAIK both would be handled as two instances of the same DLL
> because there only the file name matters, not the file path.

Right, makes sense.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Schmidt - 17 Jun 2009 18:40 GMT
>  I guess, to me, "worked" meant I was able
> to A) call the function and B) not blow up. <g>
[quoted text clipped - 3 lines]
> entry point or the DLL itself.  Does the 2nd LoadLibrary
> (VB's) succeed because we already loaded it?  Hmmm...
Yep - it succeeds, because in case of the VB-attempt, which
performs that "second, implicite" LoadLibrary - the function
will internally try to find the requested module "in memory" first.

Olaf
Karl E. Peterson - 17 Jun 2009 21:19 GMT
> "Karl E. Peterson" <karl@exmvps.org> schrieb ...
>
[quoted text clipped - 9 lines]
> performs that "second, implicite" LoadLibrary - the function
> will internally try to find the requested module "in memory" first.

Yeah, okay, that makes sense.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2010 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.