QLB files are *.EXE (look with Volkov or Norton, first bytes are MZ, after them there is valid EXE header) files with special export block data at end which contains far pointers to exported functions/subs and pointers (not sure of type) to shared vairables and COMMON blocks and various info about them. Basic symbol names are case unsensitive, UPPERCASE. There are some internal C _funcs too. However function parameter info is not stored there that's why you need *.BI with correct DECLARE, otherwise you'll crash IDE.
Only one QLB can be loaded at time. IDE loads QLB thorugh DOS exec function, debug_mode subfunction, that loads EXE into memory as child process but avoids code execution, just like normal EXE. Then QLB entry point is found propably from export block. When IDE interprets your code, before starting program it calls QLB entry point to initialize library. Then it interprets your prog as normal but when it finds an call into the QLB, it pushes all params onto the stack according to BIs DECLARE
and jumps directly into to QLB using entry point for current DECLARED function obtained from export block. If there is some error in QLB function (for exapmle you coded it in asm, with error) it may crash your IDE simply, as no checks are done. After function/sub is done it returns through normal call stack back. If it was function with INTEGER result AX register contains it, AX
X pair is for LONG result, for other types DS:AX is adress of result (in case of array, string etc).
QLB is not pure EXE, it's much more similar to compiled Qbasic code (standalone option unchecked) which requires runtime BRUN45.EXE (which in fact hooks special interrupt your exe invokes in case of calling QBs rtfuncs) and implents all QBs rtlib code. In case of QLB of course BRUN45 is not loaded (to conserve memory) but QBIDE istself implements runtime interface just like BRUN45 does. QBIDE in fact converts your interpreted code into same rtlib INT calls.
I think that with QB PDS 7.1 Pro there was simple BAS file to get pointer to that export block at end of QLB to get info about symbols exported.
Besides there is somewhere leaked QBasic 1.1 source on the net, which contains many interesting header files. I'll bet QLB export block .h or .inc file will be there. QBasic1.1 and QB45 both use same rtlib intterupt engine.
Why do you need this?
EDIT:
Link is on this forum
http://forum.qbasicnews.com/viewtopic.php?t=6538 , It's QBasic1.1 source code but rtlib is highly similar