Arbortext Command Language > Functions by Alphabetical Listing > dl_call
  
dl_call
dl_call(ref[, arg1[, argn]])
 
This function calls a function in a dynamically loaded library. The ref parameter is a reference to a symbol returned by a previous call to dl_find. The remaining arguments, if any, are the parameters passed to the dynamically loaded function.
Numeric arguments are passed by value.
Strings are passed by reference. If the dynamic library being called expects 8-bit string parameters, dl_call will convert the string to 8-bit before it passes it to the library. If the library expects 16-bit Unicode strings, the string parameter is passed unchanged. Return values are not converted in this way. If necessary, the ACL code that called the library can use unpack to extract a string from a return value.
It is possible to pass a pointer to a C-style structure by using the pack function. See the example that follows.
The return value from dl_call is the value returned by the called function. If the return value is a scalar value, it may be used directly. If the return value is a pointer, then unpack must be used to convert the pointer into a string or extract parts of a structure.
The example that follows shows how to use unpack to unreference a pointer returned by a DLL function called with dl_call. In this case, the Windows API GetCommandLine, defined in kernel32.dll as "GetCommandLineA" — the ANSI version — returns a pointer to a null terminated string. unpack creates a copy of the string to be assigned to the variable cmdline so changing cmdline later does not affect the memory returned by GetCommandLine. Note that the return value is tested for null explicitly in this example, even though unpack can tolerate a null pointer and generate a null string.
dll = dl_load("kernel32")
hGetCommandLine = dl_find(dll, "GetCommandLineA")
ptr = dl_call(hGetCommandLine)
cmdline = ptr ? unpack("p", ptr) : ""
An example of passing a structure to a dynamically loaded function follows. In this case, the Windows API GetSystemTime is called, which takes a pointer to a SYSTEMTIME structure that has 8 fields of type WORD (short). The pack function creates this structure and unpack is used to convert the result into an array and to extract the member corresponding to the day of the week.
function GetDayOfWeek()
{
local dll = dl_load("kernel32")
if (!dll) {
response("Couldn't load kernel32")
return -1
}
local GetSystemTime = dl_find(dll, "GetSystemTime")
if (!GetSystemTime) {
response("Couldn't find GetSystemTime")
dl_unload(dll)
return -1
}
local timebuf = pack("s8")
dl_call(GetSystemTime, timebuf)
dl_unload(dll)
local systime[]
unpack("s8", timebuf, systime)
return systime[3]; # wDayOfWeek
}
Since only a single field of the structure is used, the unpack call in the above example could be written more simply as
return unpack("x4s", timebuf)
which would replace the last three lines of the function.
The following example calls the Windows API FindExecutable to find the executable associated with a specified file name:
function find_exe(file, dir="")
{
local dll = dl_load("shell32")
if (!dll) {
response("Couldn't load shell32")
return "";
}
local _FindExecutable = dl_find(dll, "FindExecutableA")
if (!_FindExecutable) {
response("Couldn't find FindExecutable")
dl_unload(dll)
return ""
}
local buf = pack("a255")
local h = dl_call(_FindExecutable, file, dir, buf)
dl_unload(dll)
if (h <= 32) {
response("FindExecutable failed, return " . n)
return ""
}
return unpack("A*", buf)
}
A sample call follows:
function shell_exe(filename, dir="")
{
local exename = find_exe(filename, dir)
if (exename != "") {
sh $exename $filename &; # launch program
}
}