Jack Unrue wrote:
Is there some combination of compiler macros and/or symbol macros that could be defined such that the appropriate DLL is loaded, the function pointer retrieved and then called, and then the DLL
unloaded,
at each call site? The reason I suggest that is that I see a
similar approach
being used in SWT (from Java) where they call DllGetVersion() from comctl32 and shell32, loading and unloading each DLL in
turn. The function
pointer is retrieved on-the-spot in both cases.
...which is essentially what Jörg suggested, I'm just saying maybe some macrology could hide the details.
I was not that detailed. Quite to the contrary, I had in mind a system which would locate the address once, (e.g. when evaluating def-call-out), not each time the function is called (irk!). Loading and unloading a library is - a priori - an expensive operation. I desribed a scenario where only opened libraries are queried, presumably expensive enough.
But if you really want, you *can* do the above for each foreign funcall. Some foreign libraries do that already, internally (e.g. allocate resource that some library provides, do stuff, then release library).
Luis wrote:
look at *PACKAGE* to figure out which DLL to use. That might be a silly idea.
The idea of associating a package with a library seems IMHO silly indeed, or rather short-sighted and limiting. It does not take into consideration scenarios where libraries are used dynamically. + Not all definitions are literally written in a source file by a programmer. + Some libraries tend to hide the precise location of the symbol (e.g. GL or GLU or GLext or ...). If they want to hide it, don't introduce different packages in Lisp to unhide that. Also, there's no guarantee that a symbol's home package is where you think it is -- it could come from another package. E.g. AFAIK there's not guarantee that all ~1000 ANSI-CL symbols have their home package in (find-package "COMMON-LISP"), but that's another topic.
Also, I very much came to appreciate declarative style and referential transparency. Global variables like *package* just make simple things work, but complex run-times awful or unreliable. Not what I strive for.
Proceed to an experiment: Set *read-base* and *print-base* to something other than 10, then run your favourite applications. Do you expect failure?
Regards, Jörg Höhle.