Hi Charles,
"Late binding to DLL" declares, header files, prototyping and similar stuff are
retrograde, ridiculous, and redundant.
Luckily, you are still king and god in your alpha world of Oxygen Basic.
O2 in all the three of its hypostases (IDE, Oxygen.dll, and end user executables via the O2 runtime library they are linked against) is always linked against at least four system DLLs:
kernel32.dll,
user32.dll,
oleaut32.dll, and
msvcrt.dll. Add
gdi32.dll into the bargain (BASIC without graphics primitives like LINE, CIRCLE, PSET, etc. is not a BASIC, is it?) and
be merciful to O2 users.
Since the
5 DLLs are already in the process memory regardless of the user code, spare them this monkey business messing with the Windows includes and late bindings.
1. Run the WINDOWS_LEAN_AND_MEAN set of include files
once through a utility that would convert them to the O2 IDE's table of
intellisense entries.
2.
Map the vtables of these DLLs in their entirety at
app load time dynamically into the
O2 namespace and make their APIs part of the O2 user's extra default arsenal.
Looping through the DLL export API name table is trivial. Call GetProcAddress() for each name found. This system function is more robust and reliable than manual hopping from thunk to thunk in the DLL vtable.
3. Add an
#import MM.DLL meta
(DLL name is exemplary here) to the O2 vocabulary. If the user would like to see a Windows multimedia API call in their code, they either:
- know exactly what they're doing
or
- have a corresponding MSDN page/help file open before their eyes and have no further use for any bloody headers or declares that would only flood and bloat their scripts
or both. Make this O2 meta do exactly the same as what's described in Item 2 above for each DLL the user would care to import. Loading a DLL for just one API call is
- exactly as memory consuming as pre-loading it for a zillion API calls
- nearly as time consuming as mapping a coupla hundred API names dynamically once into a permanent name table
and let late bindings be done with once and for all.
FBSL has been doing that for decades in its BASIC interpreter and DynAsm JIT compiler, and for years, additionally in separate DynC code blocks. The DynC JIT compiler uses an ELF executable object format but I'm too old and respectful to end my days roaming through the debris of an inferior OS finding out how to set up shared memory for dozens of DynC blocks I'm using in almost every FBSL app I write. And still FBSL is practically twice faster than OxygenBasic to launch a script of comparable size and complexity in the JIT compilation mode (remember oxyscheme/tinyscheme olympics?
).
(I've just had a look into my O2 folder to see what Oxygen.dll imports are, and noticed the InMemoriam.o2bas script in the root there. You are very kind, Charles, and you always have been. Thank you.)