Interfaces to regular functions

Just starting out? Need help? Post your questions and find answers here.
Moonshine
Enthusiast
Enthusiast
Posts: 263
Joined: Tue May 25, 2004 12:13 am
Location: UK

Interfaces to regular functions

Post by Moonshine »

I wrote a quick DLL today to test something. Heres the code for the DLL:

Code: Select all

ProcedureDLL TestFunction(Value.l)
  MessageRequester("DLL Message", "The value is: " + Str(Value), #PB_MessageRequester_Ok)
EndProcedure
And the test program:

Code: Select all

; InterfaceTest

Interface I_FunctionInterface
  TestFunction(a.l)
EndInterface

Global *Object.I_FunctionInterface

*Object = OpenLibrary(0, "TestLib.dll")

  *Object\TestFunction(17)
  CloseLibrary(0)
  End
What I wanted to do is to create an interface to a regular DLL function, just so the calls stay more organised, rather than lots of CallFunction's dotted through the source. Also, some of the functions need to be called many times per loop so speed is everything and I thought this would be a better alternative to keeping a big list of function pointers and using CallFunctionFast... anyways, running the above code causes a regular XP "This program has encountered a problem and needs to close etc" dialog. So either Im doing something wrong (most likely), it's not possible, or it just cant be done. Does anyone know whats going wrong? Thanks :)
Mark my words, when you least expect it, your uppance will come...
carolight
User
User
Posts: 41
Joined: Mon Feb 09, 2004 11:08 am
Location: Gold Coast, Australia

Post by carolight »

I could be wrong, but I believe Interfaces for DLLs are really for interfacing to COM / ActiveX.

You can imitate OOP using Interfaces, but I can't think why you'd want to in this case, as I don't believe it would be very fast.

Can you just create a procedure to call the DLL procedure (although this probably won't be as fast as using CallFunctionFast directly in your code)? This would be effectively the same as using Interface, which has to redirect anyway.

Code: Select all

Global *f.l

Procedure TestFunction(Value.l)
  CallFunctionFast(*f, Value)
EndProcedure

OpenLibrary(0, "TestLib.dll") 
;Get the address of the function
*f = IsFunction(0, "TestFunction")

;TestFunction is the procedure you would call throughout your code.
TestFunction(17)
CloseLibrary(0) 
End
Moonshine
Enthusiast
Enthusiast
Posts: 263
Joined: Tue May 25, 2004 12:13 am
Location: UK

Post by Moonshine »

Thanks carolight...so my pointer list would seem the best would seem the best option....

I started a procedure that basically checks all the functions exist then assigns a pointer to each function so it can be called fast....only this might get hard to manage with a few hundred pointers...

this is how it looks:

Code: Select all

procedure getpointerlist()

*f_Function1 = IsFunction(#lib, "Function1")
  *f_Function2 = IsFunction(#lib, "Function2")
...
All I can think of is to have an array, but then Id have to keep a written list or something or which index number is which function....

anyways, thanks for the help :)
Mark my words, when you least expect it, your uppance will come...
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

Moonshine,

Do you know about the DLL importer? It allows you to call DLL functions by adding an underscore after the name.

Like this:
Function1_()
Function2_(param1, param2)

The same method is used to import all the API commands.

It's very easy to do. Just look at the ReadMe in "PureBasic\Library SDK\DLL Importer"
Moonshine
Enthusiast
Enthusiast
Posts: 263
Joined: Tue May 25, 2004 12:13 am
Location: UK

Post by Moonshine »

Ah, I forgot about that...what's it like for speed?
Mark my words, when you least expect it, your uppance will come...
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

It should be the fastest available method.
User avatar
GedB
Addict
Addict
Posts: 1313
Joined: Fri May 16, 2003 3:47 pm
Location: England
Contact:

Post by GedB »

If you simply must have an array of function pointers, here's how to do it using an interface:

Code: Select all

;An interface is actuall a specialised form of structure.  
;The first element of an interface always points to a vTable.
;A vtable is a list of Function pointers.
;Notice that the paramater list is different
;to the functions that they are going to point to.
Interface Functions
  First()
  Second(long.l)
  Third(string.s)
  Fourth()
  Fifth(fzero, *fzero)
EndInterface

;When a function is called via an interface
;The rest of the interfaces structure after 
;the vtable pointer is passsed as the first 
;paramater.  Here we are just ignoreing it.
Procedure One(ignore)
  Debug ignore
  Debug "1"
EndProcedure

;Failure To add ignore to your paramater list
;would mess up any paramaters passed.
Procedure Two(param.l)
  Debug "2 " + Str(param)
EndProcedure

Procedure Three(ignore, param.s)
  Debug "3" + param
EndProcedure

;If there are no paramaters you can ignore them,
;but it's a good idea to leave the ignore
;paramater there, to remind yourself.
Procedure Four()
  Debug "4"
EndProcedure

;Since our vtable follows imediatly after
;the pointer in this example, ignore
;actually points the the vtable.
;Ie. ignore will hold a pointer to 
;f(1), which is the same as the content
;of f(0).  This is just a coincidence
;because of the way the array has been 
;used.
Procedure Five(ignore, fzero, *fzero)
  Debug Str(PeekL(ignore)) + " = " + Str(fzero)
  Debug Str(ignore) + " = " + Str(*fzero)
EndProcedure

Dim F.l(5)

;f(0) is going to be the pointer to the vtable, 
;which is the rest of the array.
F(0) = @F(1)

;The rest of the array is the vTable.  Each element
;is pointing to a function.
F(1) = @One()
F(2) = @Two()
F(3) = @Three()
F(4) = @Four()
F(5) = @Five()

do.Functions = @F(0)

do\First()
do\Second(2)
do\Third("Three")
do\Fourth()
do\Fifth(F(0), @F(0))
Moonshine
Enthusiast
Enthusiast
Posts: 263
Joined: Tue May 25, 2004 12:13 am
Location: UK

Post by Moonshine »

Thanks for the code GedB - youve really established yourself as quite an expert on this :)
Mark my words, when you least expect it, your uppance will come...
Post Reply