Page 1 of 3

Using DLLs with WinAPI

Posted: Sun Aug 07, 2005 2:01 am
by Killswitch
Hey,

I'm wondering if there is a way to load a .dll and use its functions in PureBasic soley through the use of the WinAPI?

Thanks for your help,

Killswitch

Posted: Sun Aug 07, 2005 3:25 am
by Max.
Have a look at this thread (good sample by Jack):

viewtopic.php?t=14787

and this one from MSDN

http://msdn.microsoft.com/library/defau ... erence.asp

Posted: Sun Aug 07, 2005 11:57 am
by Killswitch
Thanks, but I'm not sure how to change the first example to suit my needs - I don't know any ASM see...

Posted: Sun Aug 07, 2005 1:28 pm
by Max.
What functions do you want to call?

Posted: Thu Aug 11, 2005 12:08 am
by Killswitch
Any function from any .dll - but any example on how to do this will be great :D

Posted: Thu Aug 11, 2005 12:56 am
by Paul
Here is an example calling GetCurrentDirectory which is found in the Kernel32.DLL ...


First using PB's built in ability to access API:

Code: Select all

CurDir$=Space(512)
GetCurrentDirectory_(512,@CurDir$)
Debug CurDir$

Next using PB commands to access command in DLL:

Code: Select all

If OpenLibrary(0,"kernel32.dll")
  CurDir$=Space(512)
  CallFunction(0,"GetCurrentDirectoryA",512,@CurDir$)
  Debug CurDir$
  CloseLibrary(0)
EndIf

Finally using strickly Windows API:

Code: Select all

module=LoadLibrary_("kernel32.dll")
If module
  GetCurrentDirectory=GetProcAddress_(module,"GetCurrentDirectoryA") 
  size.l=512
  CurDir.l= 0
  ptrDir.l = @CurDir
  
  !PUSH [v_ptrDir]
  !PUSH [v_size]
  !CALL [v_GetCurrentDirectory]

  Debug PeekS(@CurDir)
  
  FreeLibrary_(module)
EndIf

Hope this helps :)

Posted: Thu Aug 11, 2005 11:19 am
by Killswitch
It does, thanks!

Posted: Thu Aug 11, 2005 1:40 pm
by Kale
Paul wrote:

Code: Select all

module=LoadLibrary_("kernel32.dll") 
If module 
  GetCurrentDirectory=GetProcAddress_(module,"GetCurrentDirectoryA") 
  size.l=512 
  CurDir.l= 0 
  ptrDir.l = @CurDir 
  
  !PUSH [v_ptrDir] 
  !PUSH [v_size] 
  !CALL [v_GetCurrentDirectory] 

  Debug PeekS(@CurDir) 
  
  FreeLibrary_(module) 
EndIf
i might be going mad here but browsing that code i noticed something that didn't quite gel. doesn't this line:

Code: Select all

CurDir.l= 0
have to be:

Code: Select all

CurDir.s= ""
:?:

Posted: Thu Aug 11, 2005 2:48 pm
by Paul
Kale wrote: i might be going mad here but browsing that code i noticed something that didn't quite gel. doesn't this line:

Code: Select all

CurDir.l= 0
have to be:

Code: Select all

CurDir.s= ""
:?:
LOL ... If it had to be then you would get an error :)

I happened to use memory addresses in the last example, which is why I used PeekS() to display the string which was located at the memory address in CurDir.l
It was more to show the use of pointers. Since PB is so flexable with the way it handles pointers to strings, I could have just as easily done this:

Code: Select all

module=LoadLibrary_("kernel32.dll")
If module
  GetCurrentDirectory=GetProcAddress_(module,"GetCurrentDirectoryA") 
  size.l=512
  CurDir.s= ""

  !PUSH [v_CurDir]
  !PUSH [v_size]
  !CALL [v_GetCurrentDirectory]

  Debug CurDir
  
  FreeLibrary_(module)
EndIf
When I posted my example I typed it up quickly. You can always go back through code and optimize it. It was simply a quick example for Killswitch. Remember, there is always more than one way to accomplish a task. ;)

Posted: Thu Aug 11, 2005 2:55 pm
by Kale
no i'm not trying to optimise anything i just thought i spotted an error (or feature). The second example you've just posted make more sense because you are using a string to store a string and then referencing it using the pointer contained within the string var but in the first example there is no string created to store the directory path. I'm just not sure how the first example works. :oops:

Posted: Thu Aug 11, 2005 3:09 pm
by Dare2
Me either.

I would have thought it was using an unallocated bit of memory to store the result.

(This is not criticism, mind, just curiosity. A desire to learn.)

Posted: Thu Aug 11, 2005 3:11 pm
by thefool
does this help:

Code: Select all

blabla.l=1635345768
Debug PeekS(@blabla)
pauls code just throws bytes against the memory adress in ptrDir.l.
basically its the same. look at it as in assembler, a string is basically just an array of characters in ascii value's.

Posted: Thu Aug 11, 2005 3:30 pm
by Dare2
thefool wrote:does this help:

Code: Select all

blabla.l=1635345768
Debug PeekS(@blabla)
pauls code just throws bytes against the memory adress in ptrDir.l.
basically its the same. look at it as in assembler, a string is basically just an array of characters in ascii value's.
Not really.

Where is the reserving of or allocating of that memory space done?

As we agreed elsewhere, I can be quite stupid sometimes .... :)

Posted: Thu Aug 11, 2005 3:34 pm
by thefool
Dare2 wrote: Where is the reserving of or allocating of that memory space done?

As we agreed elsewhere, I can be quite stupid sometimes .... :)
hehe :D

well, i guess it is dynamic..

like:

Code: Select all

variableone=0
variabletwo=292991

variableone=variabletwo
Where is the memory reserving there?

My guess is, that it is not needed for longs and that stuff, only for strings!
(only a guess, but sounds correct in my ears)

Posted: Thu Aug 11, 2005 3:42 pm
by Dare2
I've just worked out what is going on. :oops: Live and learn!

I guess that approach be used for any call to an API function then? (Provided you know the # of pars, etc, and stack the values as appropriate)?