FB II COMPILER
Call external code resources
We use a Nubus card or a scsi device (macadios from GW Instrument) to acquire voltage signal versus time. We wrote quickbasic applications to pilot those data acquisitions. These applications are still working thanks to CleanLaunch and its (everyday) blessed author. But I would like to rewrite these programs in FBII (FB^3 if Staz tell me how to order).
Both card and acquisition device are sold with pieces of software that allows quickbasic (and other languages) user to access specific functions.
You just have to declare
LIBRARY "SCSIio interface"
in the Mac Adios example, to get the new functions available.
I don't find how to do the same from Future Basic.
A library in this sense is just a code resource or a collection of code resources.
1. Use ResEdit to copy the library to your FB program's resource file (the file that is identified with the RESOURCES statement near the start of your FB program). Make a note of the resource type and id of the library functions that you need.
2. Be sure you know what arguments (parameters) the library function expects, and how they are to be passed. This is the hard part. If you have a choice of different calling conventions (that is different versions of the same library), choose the pascal-style library in step 1 above because the calling conventions are standardised and easy to set up from FB. I do not know what the QuickBasic calling convention is.
3. Load the required resource, lock it and dereference the handle to give a pointer to the code resource. Then you jsr to the pointer value to call the code.
In the example code, the library function is of type CODL, id 1000. It expects 2 pascal stack-type arguments and returns a function value on the stack.
LOCAL FN LoadXcuteLibFunction&(id, arg1&,arg2&) DIM myHandle&,err,codePtr&,result& myHandle& =FN GETRESOURCE(_"CODL", id) LONG IF myHandle& err=FN HLOCK(myHandle&) codePtr&=[myHandle&] ' de-reference handle ` subq.l #4,sp ; space for returned function value ` move.l ^arg1&,-(sp) ; two Pascal-type stack arguments ` move.l ^arg2&,-(sp) ` move.l ^codePtr&,a0 ` jsr (a0) ; call the start of the code resource ` move.l (sp)+,^result& ; returned result err=FN HUNLOCK(myHandle&) CALL RELEASERESOURCE(myHandle&) XELSE PRINT "Resource not found" result&=0 END IF END FN=result& answer&=FN LoadXcuteLibFunction&(1000, arg1&,arg2&)4. Optional optimisation. Loading the resource is slow, so we do it once only, and remember the code pointer for fast calling. We don't bother with HUNLOCK and RELEASERESOURCE, since those will happen automatically when our application ends.
DIM gCodePtr1000& END GLOBALS LOCAL FN LoadLibFunction&(id) DIM myHandle&,err,codePtr& myHandle& =FN GETRESOURCE(_"CODL", id) LONG IF myHandle& err=FN HLOCK(myHandle&) codePtr&=[myHandle&] ' de-reference handle XELSE PRINT "Resource not found" codePtr&=0 END IF END FN=codePtr& LOCAL FN XcuteLibFunction&(codePtr&, arg1&,arg2&) ` subq.l #4,sp ; space for returned function value ` move.l ^arg1&,-(sp) ; two Pascal-type stack arguments ` move.l ^arg2&,-(sp) ` move.l ^codePtr&,a0 ` jsr (a0) ; call the start of the code resource ` move.l (sp)+,d0 ; returned result END FN gCodePtr1000&=FN LoadLibFunction&(1000) ' do once at program start-up IF gCodePtr1000&=0 THEN STOP answer&=FN XcuteLibFunction&(gCodePtr1000&, arg1&,arg2&) ' fast call