It is currently Sun Dec 16, 2018 4:09 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Calling dll with an unknown # of parameters.
PostPosted: Tue Nov 27, 2018 4:05 am 
Offline
Addict
Addict
User avatar

Joined: Wed Feb 17, 2010 12:00 am
Posts: 1324
Location: (Embarrassed to say country)
I have an app (syslog server) that does filtering & runs rules based on incoming data.
One of the requests I have is, instead of running a program, is to call a dll.
I have a few options:
1) make the requirement for the dll be a fixed function name & fixed variable / structure list.
2) do what the client wants (they're paying me)

Which is: they specify a dll and function, and what parameters to send. This can be a varying number of parameters. This precludes specifying a structure as a parameter -- but what I can't wrap my head around is how to call it.

my initial thought was to figure out the parameter count, and then just have a select paramCount and callFunction() set up with varying parameters.
BUT... this is a problem, parameters could be string, byte, word, long in any order....

I thought about using something like lua scripting and pass system variables to it & write out the parameter list.
Then I thought it might be easier to RunDLL32, but this requires specific dll format.

So, before I get vested in one of those -- anyone have any ideas?


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Tue Nov 27, 2018 9:59 pm 
Offline
Addict
Addict

Joined: Sun Apr 12, 2009 6:27 am
Posts: 3147
Hi
Search for "PBOSL GlobalSharedMemory"
Or
Share map bet Dll & application by idle
See which one suit you

_________________
Egypt my love


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Tue Nov 27, 2018 11:56 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5770
Location: Germany
If you want to do full dynamic calls into an unknown dll you could use libFFI: https://sourceware.org/libffi/ Although this is probably some work to integrate into PB.

A simpler solution that could still work quite well especially if you can limit the max number of parameters and maybe even the allowed parameter types is simply to have a list of "dispatcher" procedures in your code for various parameter combinations. Then select the right one at runtime and call that.

Like this:
Code:
; no parameters
Prototype Proto001()
Procedure Dispatch001(FunctionPointer.Proto001, Array Args.s(1))
  FunctionPointer()
EndProcedure

; one integer arg
Prototype Proto002(Arg1.i)
Procedure Dispatch002(FunctionPointer.Proto002, Array Args.s(1))
  FunctionPointer(Val(Args(0)))
EndProcedure

;...

; more complex combination
Prototype ProtoXXX(Arg1.i, Arg2.f, Arg3.s)
Procedure DispatchXXX(FunctionPointer.ProtoXXX, Array Args.s(1))
  FunctionPointer(Val(Args(0)), ValF(Args(1)), Args(2))
EndProcedure


Each PB procedure has the same arguments (function pointer and array of string parameters) so it can be called through a common prototype. It then does the actual call into the dll function with the properly converted parameters.

Then you can create a table that describes the dispatcher functions like this:
Code:
DataSection
  DispatcherData: 
  ;      Function pointer  Parameter List                   End of entry
  Data.i @Dispatch001(),                                    -1
  Data.i @Dispatch002(),   #PB_Integer,                     -1
 
  ;...
  Data.i @DispatchXXX(),   #PB_Integer, #PB_Float, #PB_String, -1
 
  ; end of data
  Data.i 0
EndDataSection


The code to call the dll would then need to scan this table for the right parameter combination, get the dispatcher pointer and just call it with the real dll function and array of arguments as a string.

You could build this glue code by hand or write a small PB program to generate it for you. This will of course not allow all possible combinations of parameters, but you could generate enough such dispatcher functions so it is flexible enough for your customer.

_________________
quidquid Latine dictum sit altum videtur


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Wed Nov 28, 2018 4:59 am 
Offline
Addict
Addict
User avatar

Joined: Wed Feb 17, 2010 12:00 am
Posts: 1324
Location: (Embarrassed to say country)
Thank you @Rashad, @idle.

#idle -- that was one of my ideas, but it seemed to become overwhelming.
I asked if I could just send addresses rather than values, then this becomes a lot more simple.
(ie: v=10 dllFunc( @v ) )
Then, it's just a matter of calling func based on # of parameters, rather than type too.

You both have given me ideas & I am reading them now. Thank you very much! I appreciate your time.

Cheers
-josh


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Wed Nov 28, 2018 10:46 am 
Offline
Addict
Addict
User avatar

Joined: Fri Sep 21, 2007 5:52 am
Posts: 3346
Location: New Zealand
Not sure which post Rashad was meaning, I did answer a similar question recently but I can't remember the details.

If you get desperate this might work out.

Code:
Structure PBAny
  type.b
  StructureUnion
    a.a
    b.b
    c.c
    u.u
    w.w
    l.l
    i.i
    f.f
    q.q
    d.d
    *ptr
  EndStructureUnion
  s.s
EndStructure   

Structure PBAnyArray
  count.l
  any.PBAny[0]
EndStructure

Procedure MyFunction(*Params.PBAnyArray)
 Protected a
 
 For a = 0 To *Params\count -1   
  Select *Params\any[a]\type
    Case #PB_Word
      Debug *Params\any[a]\w
     
    Case #PB_Quad
      Debug *Params\any[a]\q
     
    Case #PB_Double
      Debug *Params\any[a]\d
     
    Case #PB_String
      Debug *Params\any[a]\s

  EndSelect
  Next
EndProcedure

Procedure FreePBAnyArray(*ar.PBAnyArray)
  Protected a
  For a = 0 To *ar\count-1
    ClearStructure(*ar\any[a],PBAny)
  Next
 FreeMemory(*ar)
EndProcedure

Macro NewPBAny(ptr,size)
 ptr = AllocateMemory(SizeOf(PBAnyArray)+(SizeOf(PBAny)*size))
 ptr\count = size 
EndMacro   

Define *params.PBAnyArray

NewPBAny(*params,4)

*params\any[0]\type = #PB_Word
*params\any[0]\w = 12345

*params\any[1]\type = #PB_Quad
*params\any[1]\q =  123456789

*params\any[2]\type = #PB_Double
*params\any[2]\d =  2 * #PI

*params\any[3]\type = #PB_String 
*params\any[3]\s = "PureBasic V5.51 Beta 1 x64"

MyFunction(*params)

FreePBAnyArray(*params)

_________________
Got winter blues?
Enjoy a Caravan Trip into, "The Land of Grey and Pink", wine and punk weed optional!
https://www.youtube.com/watch?v=9hmFzGTxod4


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Wed Nov 28, 2018 10:52 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Feb 17, 2010 12:00 am
Posts: 1324
Location: (Embarrassed to say country)
idle wrote:
Not sure which post Rashad was meaning, I did answer a similar question recently but I can't remember the details.

Rashad was replying to another post... I knew what it was referencing.

Quote:

If you get desperate this might work out.


I'm only in control of the calling program, not the receiver dll.
One of my initial suggestions was to pass an array of variables, much like your example, an array of structured elements, which include the type of variable.

I'm investing time/energy into dynamically creating a lua script & calling it. I think this will be the cleanest way & to the customer, will only appear as doing what they want.

Code:
Structure PBAny
  type.b
  StructureUnion
    a.a
    b.b
    c.c
    u.u
    w.w
    l.l
    i.i
    f.f
    q.q
    d.d
    *ptr
  EndStructureUnion
  s.s
EndStructure   

Structure PBAnyArray
  count.l
  any.PBAny[0]
EndStructure

Procedure MyFunction(*Params.PBAnyArray)
 Protected a
 
 For a = 0 To *Params\count -1   
  Select *Params\any[a]\type
    Case #PB_Word
      Debug *Params\any[a]\w
     
    Case #PB_Quad
      Debug *Params\any[a]\q
     
    Case #PB_Double
      Debug *Params\any[a]\d
     
    Case #PB_String
      Debug *Params\any[a]\s

  EndSelect
  Next
EndProcedure

Procedure FreePBAnyArray(*ar.PBAnyArray)
  Protected a
  For a = 0 To *ar\count-1
    ClearStructure(*ar\any[a],PBAny)
  Next
 FreeMemory(*ar)
EndProcedure

Macro NewPBAny(ptr,size)
 ptr = AllocateMemory(SizeOf(PBAnyArray)+(SizeOf(PBAny)*size))
 ptr\count = size 
EndMacro   

Define *params.PBAnyArray

NewPBAny(*params,4)

*params\any[0]\type = #PB_Word
*params\any[0]\w = 12345

*params\any[1]\type = #PB_Quad
*params\any[1]\q =  123456789

*params\any[2]\type = #PB_Double
*params\any[2]\d =  2 * #PI

*params\any[3]\type = #PB_String 
*params\any[3]\s = "PureBasic V5.51 Beta 1 x64"

MyFunction(*params)

FreePBAnyArray(*params)
[/quote]


Top
 Profile  
Reply with quote  
 Post subject: Re: Calling dll with an unknown # of parameters.
PostPosted: Thu Nov 29, 2018 11:07 am 
Offline
Addict
Addict
User avatar

Joined: Wed Feb 17, 2010 12:00 am
Posts: 1324
Location: (Embarrassed to say country)
Well; That was fun...

I enjoyed adding lua scripting to my app; it was suprisingly easy. but one thing I overlooked; lua has no native way to call a standard dll function; only way is thru extensions (which aren't pre-compiled). I will have to go back and try to negotiate a working solution. Grr. Services me right -- I just assumed a modern scripting engine would support calling native shared objects / dll. (Oh, it does support calling dll's, but only dll's that are coded for lua; which, in my case, defeats the purpose, as I need to call existing standard dll functions)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye