Panoramic programs can use DLL's through a dedicated set of command:
==> this command dynamically loads the DLL dllfilename (error if a DLL is already loaded)
result% = DLL_call0("dllfunction") result% = DLL_call1("dllfunction",par1) ... result% = DLL_call6("dllfunction",par1,par2,par3,par4,par5,par6)
==> these functions call a function named dllfunction in the previously loaded DLL, along with the specified parameters, and returns an integer result. Please note that the dllfunction name must respect upper/lower case of the desired function name. (error if no DLL is loaded)
==> this command unloads the previously loaded DLL (error if no DLL is loaded)
It is immediately obvious that at any time, no more than one DLL can be handled simultaneously by Panoramic. Thus, if a program needs access to several different DLL's, the DLL_on and DLL_off commands must be used each time to switch between DLL's.
Technically, this might be acceptable, but it's not very efficient, neither in terms of performance nor in terms of elegance. Even more, this might be prohibitive for usage of certain DLL functions. With system DLL's, you might explore a folder tree, an object list or whatsoever. All these API functions relay on the implicit assumption that the link between the DLL and the calling program is not broken, otherwise, the context is gone. If at any step, you need a DLL function from another DLL, you are blocked - no way to do this in Panoramic !
Here is where my special DLL management comes in !
I have written a special DLL managing the dynamically loading of other DLL's, in a way unknown to Panoramic ! The only DLL known by Panoramic is this special DLL, the rest is done internally ! And thus, the Panoramic DLL loading restriction is gone !
This special DLL is called DynamicallyLoadDLL.dll. Now, we are still under Panoramic. Thus, Panoramic's calling conventions apply. At program start, you load this DLL once:
At the end of the program, don't forget to unload it:
After loading this DLL, all other DLL functions are managed through it. First, you have to load all the other DLL's you want to use simultaneously at any given time. This is done by:
handle_DLL% = dll_call1("LoadDLL", adr(dll_name$))
handle_DLL% is the Windows handle of the dynamically loaded DLL. There must by such an integer variable for each simultaneously loaded DLL. This variable will be used to reference the target DLL until it is unloaded again. LoadDLL is the name of the DynamicallyLoadDLL function doing the work. dll_name$ is a string variable holding the name of the DLL to be loaded. And as Panoramic only passes integers by value to the DLL_call functions, the variable must be passed using its physical address, so we use adr().
When a DLL loaded this way is no longer required, it is the responsability of the program to unload it properly. NEVER forget to unload a loaded DLL ! This is done by:
result% = dll_call1("UnLoadDLL", handle_DLLl%)
result% is the function's result value which in this case is irrelevant. handle_DLL% is the DLL's handle returned by the LoadDLL function.
Now, there is a problem. Panoramic calls DLL functions by the DLL_callx function, where x is the number of runtime parameters. The maximum parameter number is 6, plus the name of the desired function. But in the situation of multiple DLL's, the target DLL must be identified too. And the call function of the DynamicallyLoadDLL must be specified too, thus eating up 2 parameters ! So, there is a function to "target" the desired DLL along with the desired function within this DLL. DynamicallyLoadDLL will internally remember the targeted function. We can now use the call function of DynamicallyLoadDLL which is more or less a wrapper arround the DLL_callx function of Panoramic.
Targetting is done by:
result% = dll_call2("TargetDLL", handle_DLL%, adr(funct$))
result% is the function's result value which in this case is irrelevant. handle_DLL% is the DLL's handle returned by the LoadDLL function. funct$ is a string containing the name of the desired DLL function. Please remember: the function name MUST be a variable and passed by adr().
Calling the targeted function is done by:
result% = dll_call0("CallDLL0") result% = dll_call1("CallDLL1",p1) result% = dll_call2("CallDLL2",p1,p2) result% = dll_call3("CallDLL3",p1,p2,p3) result% = dll_call4("CallDLL4",p1,p2,p3,p4) result% = dll_call5("CallDLL5",p1,p2,p3,p4,p5) result% = dll_call6("CallDLL6",p1,p2,p3,p4,p5,p6)
result% is the targeted function's result. p1...p6 are the parameters passed to the DLL function.
Note: the functions called by Panoramic are CallDLLx which are the wrapper functions residing within DynamicallyLoadedDLL.dll. These functions will call the last targeted DLL function using the actual parameters.
Now, with this technique, Panoramic's restrictions are overcome.
The distribution contains other DLL's, along with complete documentation and demo programs, especially a "Test DynamicallyLoadDLL.bas" program demonstrating the possibilities of this module. The distribution is available through the following link:
or at my website:
As all other programs proposed on my website, this module is complete freeware; sources are provided or may be obtained for free using the contact form.
IMPORTANT NOTE: ALWAYS UNLOAD DYNAMICALLY LOADED DLL'S WHEN NO LONGER NEEDED !