Passing Single-Precision Data Between QuickBASIC and MPW C (59487)






This article was previously published under Q59487

SUMMARY

The two programs below demonstrate how a Microsoft QuickBASIC program can pass single precision variables to and from Apple MPW (Macintosh Programmer's Workshop) C version 3.00 pure code resources.

This information about interlanguage calling applies to Microsoft QuickBASIC version 1.00 for the Apple Macintosh.

MORE INFORMATION

When doing interlanguage calling with Microsoft QuickBASIC, the other language can make calls to the BASIC run time 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 PrintSng.c from Apple MPW C version 3.00 as follows:
   c -p PrintSng.c

   link -p -c MSBB -o PrintSng -rt MBPC=2 -t MBPC -sn Main=PrintSng
   BasicLib.a.o PrintSng.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, PrintSng is a pure code resource that can be used with the RetSng QuickBASIC program.

It should be noted that PrintSng uses the record structure BigRec to pass the single-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 RetSng, which invokes an Apple MPW Pascal routine to return a series of single-precision numbers:
   LIBRARY "PrintSng"
   A! = 0 : B! = 0 : C! = 0
   CALL PrintSng(A!, B!, C!)
   PRINT A!; B!; C!
   WHILE INKEY$ = "" : WEND
				
The following Apple MPW C routine is PrintSng.c, which accepts a series of passed single-precision numbers from a Microsoft QuickBASIC program and returns a constant value in them:
/**************************************************************
 * PrintSng.c (c) 1989 Microsoft Corporation                  *
 **************************************************************
 * Description: Example to show how to pass single-precision  *
 *              numbers from QuickBASIC to MPW C and back.    *
 **************************************************************/ 

#include "BasicMPWC.h"

struct BigRec {
   SINGLE singlenum;
};

pascal void AssignSng(LIBARGPTR ptr, struct BigRec val) = {
   0x225F,  /* movea.l (a7)+,a1                               */ 
   0x2E19,  /* move.l  (a1)+,d7   ;get single precision value */ 
   0x205F,  /* movea.l (a7)+,a0   ;get ptr to variable        */ 
   0x20C7   /* move.l   d7, (a0)+ ;assign the value           */ 
};

/*------------------------------------------------------------*
 * A routine to pass back to BASIC single-precision constants *
 *    Called from BASIC as:                                   *
 *    CALL PrintSng (< single 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 == _SINGARG) {
            tempdbl.singlenum = 123.456;
            AssignSng(valptr, tempdbl);
         }
      argtype = GetNextLibArg(&valptr, &tempflag);
   }

} /* MAIN */ 
				
Running RetSng produces the following output:
   123.456  123.456  123.456
				

Modification Type: Minor Last Reviewed: 1/8/2003
Keywords: KB59487