Loading dll dynamically

Loading dll dynamically

Post by Marco Ner » Sat, 29 Jan 2000 04:00:00



Hi all,

how can I use classes and functions inside a dll (written by VO 2.5)
using LoadLibrary function ?

Thank you in advance

  m.neri.vcf
< 1K Download
 
 
 

Loading dll dynamically

Post by Wong » Sat, 29 Jan 2000 04:00:00


Hi Marco,

I have written something for our HRMS project, still a lot of thing to be
done, but for an example,  I think should be alright.

Regards,
Wong

PCall.exe DLLName Arg ...
---------------------------------------

//e:\wong\prg\pcall.prg 21-Jan-2000 01:45:44  Jacky
FUNCTION Start() AS INT
  //GetUserName(), GetHostName(), NetName(), SetAnsi(.F.)
  //SetCollation(#Clipper), Enable3DControls(), WorkDir(), CurDir()
  LOCAL aoClass AS ARRAY, iSub AS INT, dwALen AS DWORD, acArgV AS ARRAY, ;
    iArgC AS INT, oModule AS HRModule, iExitCode AS INT
  aoClass:={HRError{}}
  iSub:=1
  dwALen:=ALen(aoClass)
  DO WHILE iSub<=dwALen .AND. aoClass[iSub]:lInit()
    ++iSub
  ENDDO
  IF iSub==dwALen+1
    oModule:=HRModule{}
    BEGIN SEQUENCE
      acArgV:=acArgV()
      HRError{}:vAssert(At("PCALL.EXE",acArgV[1])!=0,;
        "Start up file must be PCALL.EXE",{acArgV[1]})
      iArgC:=INT(ALen(acArgV))
      HRError{}:vAssert(iArgC>=2,"DLL basename needed",{})
      oModule:oLoadLibrary(acArgV[2])
      acArgV[2]:=oModule:cGetModuleFileName()
      iExitCode:=oModule:iMain(iArgC,acArgV)
    END SEQUENCE
    oModule:vFreeLibrary()
  ENDIF
  DO WHILE --iSub>=1
    aoClass[iSub]:vAxit()
  ENDDO
  MemoWrit("CON.DOS",_Chr(7)) //If program hang, will not beep
RETURN (iExitCode)

FUNCTION acArgV() AS ARRAY PASCAL
  //acArgV.prg 15-Jan-00
  LOCAL cStr AS STRING
  LOCAL dwPos AS DWORD
  LOCAL acArgV AS ARRAY
  cStr:=Psz2String(GetCommandLine())
  cStr:=Upper(SubStr(AllTrim(cStr),2))
  dwPos:=At('"',cStr)
  acArgV:={Left(cStr,dwPos-1)}
  cStr:=AllTrim(SubStr(cStr,dwPos+1))
  HRError{}:vAssert(At('"',cStr)==0,'"(double quote) does not allow',{cStr})
  DO WHILE !Empty(cStr)
    dwPos:=At(' ',cStr)
    IIf(dwPos==0,dwPos:=SLen(cStr)+1,NIL)
    AADD(acArgV,Left(cStr,dwPos-1))
    cStr:=AllTrim(SubStr(cStr,dwPos+1))
  ENDDO
RETURN (acArgV)

CLASS HRError INHERIT Error
        //HRError  
DECLARE METHOD lInit
DECLARE METHOD vAxit
DECLARE METHOD lAlert
DECLARE METHOD vAssert

METHOD lInit() AS LOGIC PASCAL CLASS HRError
RETURN (.T.)

METHOD vAxit() AS VOID PASCAL CLASS HRError
RETURN

METHOD lAlert(lValid AS LOGIC,cDescription AS STRING,auArgs AS ARRAY) ;
  AS LOGIC PASCAL CLASS HRError
  EnforceType(lValid,LOGIC)
  EnforceType(cDescription,STRING)
  EnforceType(auArgs,ARRAY)
  IF !lValid
    SELF:Args:=auArgs
    SELF:Description:=cDescription
    SELF:CanDefault:=.T.
    Eval(ErrorBlock(),SELF)
  ENDIF
RETURN (lValid)

METHOD vAssert(lValid AS LOGIC,cDescription AS STRING,auArgs AS ARRAY) ;
  AS VOID PASCAL CLASS HRError
  EnforceType(lValid,LOGIC)
  EnforceType(cDescription,STRING)
  EnforceType(auArgs,ARRAY)
  IF !lValid
    SELF:Args:=auArgs
    SELF:Description:=cDescription
    EVAL(ErrorBlock(),SELF)
  ENDIF
RETURN

//e:\wong\prg\hrmodule.prg  21-Jan-2000 01:43:37  Jacky
CLASS HRModule
DECLARE METHOD lInit
DECLARE METHOD vAxit
DECLARE METHOD oLoadLibrary
DECLARE METHOD iMain
DECLARE METHOD vFreeLibrary
DECLARE METHOD cGetModuleFileName
PROTECT ptrModule AS PTR
PROTECT cModule AS STRING

METHOD lInit() AS LOGIC PASCAL CLASS HRModule
RETURN (.T.)

METHOD vAxit() AS VOID PASCAL CLASS HRModule
  HRError{}:lAlert(GetModuleHandle(String2Psz(SELF:cModule))==NULL_PTR,;
    SELF:cModule+" still loaded")
  HRError{}:lAlert(SELF:ptrModule==NULL_PTR,"SELF:ptrModule==NULL_PTR")
RETURN

METHOD oLoadLibrary(cModule AS STRING) AS HRModule PASCAL CLASS HRModule
  SELF:cModule:=cModule
  SELF:ptrModule:=LoadLibrary(String2Psz(cModule))
  HRError{}:vAssert(SELF:ptrModule!=NULL_PTR,"Unable to load DLL:
"+cModule,{})
RETURN (SELF)

FUNCTION iMain(iArgC AS INT, acArgV AS ARRAY) AS INT PASCAL
RETURN (0)

METHOD iMain(iArgC AS INT, acArgV AS ARRAY) AS INT PASCAL CLASS HRModule
  LOCAL ptrMain AS iMain PTR, iExitCode AS INT
  ptrMain:=GetProcAddress(SELF:ptrModule,String2Psz("iMain"))
  HRError{}:vAssert(ptrMain!=NULL_PTR,"iMain(iArgC,acArgV) not found",{})
  iExitCode:=PCALL(ptrMain,iArgC,acArgV)
RETURN (iExitCode)

METHOD vFreeLibrary() AS VOID PASCAL CLASS HRModule
  IF SELF:ptrModule!=NULL_PTR
    HRError{}:vAssert(FreeLibrary(SELF:ptrModule),"Unable to free "+;
      SELF:cModule)
    HRError{}:vAssert(GetModuleHandle(String2Psz(SELF:cModule))==NULL_PTR,;
      SELF:cModule+" still loaded")
    SELF:ptrModule:=NULL_PTR
  ENDIF
RETURN

METHOD cGetModuleFileName() AS STRING PASCAL CLASS HRModule
  LOCAL DIM abBuffer[256] AS BYTE, dwLen AS DWORD, cFileName AS STRING

  HRError{}:vAssert(dwLen!=0,"dwLen!=0")

RETURN (cFileName)

iMain.DLL
--------------
//e:\wong\prg\imain.prg 21-Jan-2000 01:28:11  Jacky
FUNCTION iMain(iArgC AS INT, acArgV AS ARRAY) AS INT PASCAL
  MessageBox(NULL,String2Psz(acArgV[2]),String2Psz("iMain"),0)
RETURN (0)



Quote:> Hi all,

> how can I use classes and functions inside a dll (written by VO 2.5)
> using LoadLibrary function ?

> Thank you in advance


 
 
 

Loading dll dynamically

Post by Marco Ner » Tue, 01 Feb 2000 04:00:00


Thank you Wong.

Your example has been helpful.

Regards.


> Hi Marco,

> I have written something for our HRMS project, still a lot of thing to be
> done, but for an example,  I think should be alright.

> Regards,
> Wong

> PCall.exe DLLName Arg ...

  m.neri.vcf
< 1K Download
 
 
 

1. Freeing 'SHFolder.dll' does not unload the DLLs it loads

Hi everyone...

I encountered a strange behaviour when freeing 'SHFolder.dll' under Windows
XP.  I need to get the path for the 'Program Files' folder, so, as
documented I decided to use SHGetFolderPath().  This is the only function I
need to use from the shell so I decided it's best to load the library
dynamically at runtime with LoadLibrary() and then unload it with
FreeLibrary().  The code is as follows:

#define CSIDL_PROGRAM_FILES    0x0026
#define SHGFP_TYPE_CURRENT    0
typedef HRESULT (__stdcall * PFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD,
LPSTR);

char* lpstrDestination = NULL;

if (lpstrDestination = reinterpret_cast<char*>(malloc(MAX_PATH)))
{
    if (hLibrary = LoadLibrary("SHFolder.dll"))
    {
        PFNSHGETFOLDERPATHA SHGetFolderPath =
reinterpret_cast<PFNSHGETFOLDERPATHA>(GetProcAddress(hLibrary,
"SHGetFolderPathA"));
        if (SHGetFolderPath && !SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES,
NULL, SHGFP_TYPE_CURRENT, lpstrDestination))
        {
            // do something
        }
        FreeLibrary(hLibrary);
    }

Now, the above code works fine and does what it is supposed to do.  However,
when calling SHGetFolderPath(), 'SHFolder.dll' loads several other
libraries: 'shlwapi.dll', 'msvcrt.dll', 'user32.dll', 'gdi32.dll', and 2
'comctl32.dll' (one from the system32 directory, and the other from the
WinSxS directory).  All seems fine till here.  The problem arises when
FreeLibrary() is called.  The function call succeedes and 'SHFolder.dll' is
unloaded from the process space, BUT... and that's a big but... all the
above mentioned DLLs which were loaded by 'SHFolder.dll' remain loaded and
are not unmapped from the address space of the process.  Note that this is
not an issue under Windows2000, maybe due to SHGetFolderPath() behaving
differently on different Win32 platforms.

Could anyone please explain why this behaviour is so under WindowsXP.  I
really don't like the idea of having several modules lying in memory which I
don't need and which I never called in the first place!

Thanking you in advance,
Clive

2. CALL_QUERY

3. REPOST: how to dynamically load a color in excel spread sheet

4. Real time sound DSP?

5. how to dynamically load a color in excel spread sheet

6. Screensaver

7. viewing dynamically loaded modules

8. Deserialization issue consuming WSDL service with choice

9. MPI on beowulf - problem with dynamically loaded libraries

10. Dynamically Loading Bitma

11. Dynamically Loading Bitmaps

12. How to find list of variables and sub routines loaded, dynamically.

13. dynamically loading/unloading an upper-layer storage filter driver.