MORE INFORMATION
When doing interlanguage calling with Microsoft QuickBASIC, the other
language can make calls to the BASIC runtime to get the address of
passed arguments. This is accomplished with the GetNextLibArg
statement.
GetNextLibArg returns a pointer to a variant record containing another
pointer to each possible type of QuickBASIC variable (single
precision, double precision, integer, etc.). Usually a double
indirection of pointers is used to get the actual passed data.
Using double indirection of pointers with LSC or Apple MPW C, however,
does not return the correct value. This is a QuickBASIC header file
problem. The routine below demonstrates how an inline
assembly-language routine can be used in place of the double
indirection to work around the problem.
More information on interlanguage calling with Microsoft QuickBASIC
can be found in the "Microsoft QuickBASIC for Apple Macintosh:
Language Reference" starting on page 444.
Compile and link PrintDbl.c from Apple MPW C version 3.00 as follows:
c -p PrintDbl.c
link -p -c MSBB -o PrintDbl -rt MBPC=2 -t MBPC -sn Main=PrintDbl
BasicLib.a.o PrintDbl.c.o
Note: The file BasicLib.a.o comes with Microsoft QuickBASIC for the
Apple Macintosh on the Examples disk in the User Libraries:MBPC
Rsrcs:MPWP PCR Folder.
Once compiled and linked, PrintDbl is a pure code resource that can be
used with the RetDbl QuickBASIC program.
Note: PrintDbl uses the record structure BigRec to pass the double
precision number to the assembly language subroutine. This is because
MPW automatically converts single and double precision numbers to an
extended 10-byte format when passing them. Using the record structure
stops MPW from performing this conversion.
Code Example
The following QuickBASIC program is RetDbl, which invokes an Apple MPW
C routine to return series of double precision numbers:
LIBRARY "PrintDbl"
A# = 0 : B# = 0 : C# = 0
CALL PrintDbl(A#, B#, C#)
PRINT A#, B#, C#
WHILE INKEY$ = "" : WEND
The following Apple MPW C routine is PrintDbl.c, which accepts a
series of passed double precision numbers from a Microsoft QuickBASIC
program and returns a constant value in them:
/**************************************************************
* PrintDbl.c (c) 1989 Microsoft Corporation *
**************************************************************
* Description: Example to show how to pass double precision *
* numbers from QuickBASIC to MPW C and back. *
**************************************************************/
#include "BasicMPWC.h"
struct BigRec {
DOUBLE dblnum;
};
pascal void AssignDbl(LIBARGPTR ptr, struct BigRec val) = {
0x225F, /* movea.l (a7)+,a1 */
0x2E19, /* move.l (a1)+,d7 ;get Long value */
0x2C19, /* move.l (a1)+,d6 ; get second part */
0x205f, /* movea.l (a7)+,a0 ;get ptr to Int variable */
0x20C7, /* move.l d7, (a0)+ ;assign the Int value */
0x20C6 /* move.l d6, (a0)+ ;assign the Int value */
};
/*------------------------------------------------------------*
* A routine to pass back to BASIC double precision constants *
* Called from BASIC as: *
* CALL PrintDbl (< double precision argument list >) *
*------------------------------------------------------------*/
PUBLIC VOID MAIN() {
INT16 tempflag, argtype;
LIBARGPTR valptr;
struct BigRec tempdbl;
argtype = GetNextLibArg(&valptr, &tempflag);
while (argtype != _ARGSEND) {
if (argtype != _NULLARG)
if (argtype == _DBLARG) {
tempdbl.dblnum = 123.456;
AssignDbl(valptr, tempdbl);
}
argtype = GetNextLibArg(&valptr, &tempflag);
}
} /* MAIN */
Running RetDbl produces the following output: