FB II Compiler

PG PRO

Debugging

Memory

System

Mathematics

Resources

Disk I/O

Windows

Controls

Menus

Mouse

Keyboard

Text

Fonts

Drawing

Sound

Clipboard

Printing

Communication

ASM

Made with FB

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.

Guy Bonnot

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
Robert