; 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...
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.
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
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...
;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))