RunTime DLL

Category: DLLs

Date: 03-28-2012

Return to Index


 
'There are times when a programmer wants to provide access to a DLL, but must take
'into account the possibility that the DLL is not present on the user's machine.  Loading
'the DLL at run-time, rather than compile-time is the solution, for which PowerBASIC
'provides the CALL DWord statement.  Used with the API LoadLibrary and
'GetProcAddress functions, Call Dword is an alternative to linking with DLLs at compile-time.
 
'In general, four steps must be taken:
'1. Declare
'use PowerBASIC Declare to define a local Sub/Function that has the same arguments
'as the function that will be called from the external DLL. It can have the same
'name as the target procedure in the external DLL.  The Sub/Function is not actually
'written, just Declare the function so the name can be used to indirectly call
'the external DLL.
 
'2. LoadLibrary
'use this API at runtime to load the DLL containing the target procedure
 
'3. GetProcAddress
'use this API to get the address of a procedure in the now-loaded DLL
 
'4. Call DWord
'use this PowerBASIC statement to run the DLL procedure, using either
'of the two syntax options for Call DWord
 
'Primary Code:
'Syntax: there are two syntax options, depending on whether the target
'procedure has arguments.  The enclosing () are required.
Call Dword dwpointer [{BDECL | CDECL | SDECL} ()]   'no arguments, default is SDECL
Call Dword dwpointer USING abc([arguments]) [TO result_var]  'arguments
 
'Use the following to get the pointer to a local sub/function:
dwPointer = CodePTR(MySub)             'address of the entry point of a local sub/function
 
'Notes on USING Syntax:
' - requires a corresponding Declare statement (no LIB clause) to create
'   a model procedure declaration
' - TO is optional, except for Functions whose return value is a non-Integer class
 
 
'Compilable Example:
#Compiler PBWin 9, PBWin 10
#Compile EXE
'#Dim All
#Include "Win32API.inc"
'Here's the target procedure in the external DLL Kernel32.DLL
'Declare Function GetDiskFreeSpaceEx LIB "KERNEL32.DLL" ALIAS "GetDiskFreeSpaceExA" _
'     (lpPath As AsciiZ, lpFreeToCaller AS QUAD, lpTotalBytes AS QUAD, lpTotalFreeBytes AS QUAD) As Long
Declare Function MyDiskFreeSpaceEx _
   (lpPath As AsciiZ, lpFreeToCaller AS QUAD, lpTotalBytes AS QUAD, lpTotalFreeBytes AS QUAD) As Long
 
Global hDlg as Dword
 
Function PBMain() As Long
   Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
   Control Add Button, hDlg, 100,"Push", 50,10,100,20
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   If CB.Msg = %WM_Command AND CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then
      Local hLib AS Dword, pAddr AS Dword,  szDrv As AsciiZ * %MAX_PATH, lResult As Long
      Local FreeToUserQuota&&, SizeOfDisk&&, TotalFree&&
      szDrv = "C:\"
      hLib = LoadLibrary("KERNEL32.DLL")
      pAddr = GetProcAddress(hLib, "GetDiskFreeSpaceExA")
      If pAddr <> 0 Then
         Call Dword pAddr USING MyDiskFreeSpaceEx(szDrv, FreeToUserQuota&&, SizeOfDisk&&, TotalFree&&) TO lResult
         MsgBox Str$(FreeToUserQuota&&) + " " + Str$(SizeOfDisk&&) + " " + Str$(TotalFree&&)
      End If
      FreeLibrary hLib
   End If
End Function
 
'gbs_00321
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm