mIRC Home    About    Download    Register    News    Help

Print Thread
$dllcall #267740 14/09/20 09:00 PM
Joined: Jan 2004
Posts: 1,433
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,433
A couple items to make $dllcall be more useful. Right now, it's difficult for a dll to know whether it's been called by $dll the normal way, or was called by $dllcall in the background, or even that it was called by the /dll command. And, it's currently not possible for $dllcall to access the return string normally returned from a dll.

(1) Another LOADINFO data item which indicates whether the dll was called by $dll or $dllcall. I assume it's fine for the bitflag to return the same for $dll or /dll, since /dll has always been used without the expectation of output or callback.

If this is made a bitflag value, future flag bits could be added to it, without further increasing the size of the structure.

This feature would make it easier for a non-threadsafe dll to behave differently if it's been called in the background by $dllcall

(2) change $dllcall syntax from
$dllcall(<filename>,<callbackalias|/noop> [optional string],<procname>,<data|$null>)
to
$dllcall(<filename>,<callbackalias|/noop> [optional string],<procname>,<data|$null>[,&binvar])

The new parm would allow the .dll's normal 'return 3;' string to be filled into the &binvar instead of $dllcall sending it to the bit bucket.

The /help currently doesn't document the callbackalias other than "and will call the specified alias once the call returns".

Currently $dllcall calls the alias-parameter with $dll(filename) appended to it, so that

$dllcall(File.dll,!echo -c info,procname,data)

will call the /echo command with $1- being: -c info $mircdirFile.dll

The new behavior could also be accomplished without the 5th parm by changing the syntax to be $dllcall(filename,&binvar alias, procname, data) as long as it's not intended that &string as an alias name not be supported.

Re: $dllcall [Re: maroon] #267741 15/09/20 09:38 AM
Joined: Apr 2004
Posts: 853
Sat Offline
Hoopy frood
Offline
Hoopy frood
Joined: Apr 2004
Posts: 853
Originally Posted by maroon
(1) Another LOADINFO data item which indicates whether the dll was called by $dll or $dllcall.

I'm afraid this suggestion is invalid, but it it is fortunately also not needed. It is invalid because LoadDll does not get called for every DLL call. Rather, LoadDll typically gets called once (depending on mKeep etc), after which a mix of calls invoked with /dll, $dll() and/or $dllcall() may follow. Thus, LOADINFO can not be used to pass in per-call information.

However, a DLL can tell very easily whether a procedure was invoked with $dllcall() or not. For example, it can store the main mIRC thread ID with a call to GetCurrentThreadId() from LoadDll, and compare that stored value to the value returned from GetCurrentThreadId() in the actual DLL procedure. If the values are the same, the procedure was called with /dll or $dll(). If the values are different, the procedure was called with $dllcall().

Originally Posted by maroon
(2) change $dllcall syntax [..]. The new parm would allow the .dll's normal 'return 3;' string to be filled into the &binvar instead of $dllcall sending it to the bit bucket.

This suggestion I don't understand. The two main advantages of binvars are 1) they can store NUL characters, and 2) they can contain more data than regular variables. However, due to the nature of the "data" parameter to DLL calls, storing the returned data into a binvar would not help with exploiting either of those advantages. Thus, how would this suggestion be an improvement over the called alias using "/bset -t" itself?


Saturn, QuakeNet staff
Re: $dllcall [Re: Sat] #267744 15/09/20 05:14 PM
Joined: Jan 2004
Posts: 1,433
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,433
OK, from testing with
variable = GetCurrentThreadId();
it looks like LoadDll is invoked using the same thread ID which will eventually be used by $dll, even if the DLL is being loaded by $dllcall, and is different than the thread ID seen by the procname being executed by that $dllcall usage. So by saving that ID during LoadDll to a global variable, that lets a procname know whether it was called using $dllcall or not.

As for a 5th parm containing the &binvarname, that may not be the best solution, because it would also require the callback alias be given a way to know which &binvarname was used. The current behavior of $dllcall(File.dll,callbackalias foo bar,procname,data) is to invoke the callbackalias with $1- being "foo bar $mircdirFile.dll", so the callbackalias would need adding &binvarname to the 2nd parm as a parameter, which may not be good for $dllcall to assume &string in parm2 is the name of the &binvar.

If backwards compatibility needs to be preserved with current behavior of the $1- for the callbackalias, perhaps a better solution would be a new $callbackstring kind of identifier which would contain the normal return3 string. Having the same temporary scope as $nick is probably sufficient, as opposed to the longterm nature of $msfile(1) or $readn.

Re: $dllcall [Re: maroon] #267746 15/09/20 06:20 PM
Joined: Apr 2004
Posts: 853
Sat Offline
Hoopy frood
Offline
Hoopy frood
Joined: Apr 2004
Posts: 853
Originally Posted by maroon
If backwards compatibility needs to be preserved with current behavior of the $1- for the callbackalias, perhaps a better solution would be a new $callbackstring kind of identifier which would contain the normal return3 string.

Yes, I have to say I misunderstood your original second point. It would definitely be good if there were a way (any way!) for the custom alias of a $dllcall() call to obtain the data value returned from the DLL.


Saturn, QuakeNet staff