KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q68663: Passing BASIC Numeric Arrays from BASIC to C and Back to BASIC

Article: Q68663
Product(s): See article
Version(s): 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# S910114-113 B_BasicCom | mspl13_basic
Last Modified: 29-JAN-1991

The following example demonstrates how to pass numeric arrays from
compiled BASIC to Microsoft C then back to BASIC using BASIC's "by
reference" calling convention.

This information applies to Microsoft QuickBASIC 4.00, 4.00b, and 4.50
for MS-DOS, to Microsoft BASIC Compiler 6.00 and 6.00b for MS-DOS and
MS OS/2, and to Microsoft Professional Development System 7.00 and
7.10 for MS-DOS and MS OS/2.

For more information about passing other types of parameters between
BASIC and C, and a list of which BASIC and C versions are compatible
with each other, query in the Software/Data Library for the following
word:

    BAS2C

The example below differs from the other BAS2C array-passing examples
in that the example below lets you pass array data from BASIC to C
then back to BASIC. The other BAS2C examples pass array data from
BASIC to C but not back to BASIC.

Code Example
============

Compile and link the sample programs below as follows:

   BC /O ByRefB.BAS ;
   CL /c /W3 /AM ByRefC.C
   LINK /NOE ByRefB ByRefC ;

ByRefB.BAS
----------

' Declare the BASIC and C routines to use the same calling
' convention. In this case we want the BASIC "BY REFERENCE"
' calling convention.

DECLARE SUB BTest (Array1%(), Array2!(), Array3#(), Array4&())
DECLARE SUB CTest (Array1%(), Array2!(), Array3#(), Array4&())
' $STATIC
DIM A%(10), B!(10) ' Define some STATIC data in "DGROUP"
' $DYNAMIC
DIM C#(10), D&(10) ' And, some DYNAMIC data
CLS
FOR i% = 0 TO 10   ' Initialize the arrays
    A%(i%) = i%
    B!(i%) = .5 * i%
    C#(i%) = 1.5 * i%
    D&(i%) = i% * i%
NEXT i%
CTest A%(), B!(), C#(), D&()
PRINT A%(10), B!(10), C#(10), D&(10)
END
SUB BTest (Array1%(), Array2!(), Array3#(), Array4&())
    PRINT
    FOR i% = 0 TO 10
        PRINT Array1%(i%), Array2!(i%), Array3#(i%), Array4&(i%)
    NEXT i%
END SUB

ByRefC.C
--------

#include <stdio.h>

/**
 ** Use "typedef" to reduce complexity/readability of code.
 **
 ** BASIC's BY REFERENCE is a near handle to a far pointer for the
 ** actual data of numeric arrays.
 **/
typedef int    far * near * HInt ;
typedef long   far * near * HLng ;
typedef float  far * near * HSng ;
typedef double far * near * HDbl ;

/**
 ** Define the BASIC routine as a "standard BASIC" call so the
 ** parameters will be the same.
 **/
extern void pascal BTest ( HInt, HSng, HDbl, HLng ) ;

/**
 ** Define our C routine as a "standard BASIC" routine so we look
 ** like BASIC. This simplifies the parameter passing since we
 ** all look the same on the stack.
 **/
void pascal CTest (HInt IntArray, HSng SngArray,
                   HDbl DblArray, HLng LngArray)
    {
        int j, i;
        printf ("\nOriginal Array Values\n") ;
        BTest ( IntArray, SngArray, DblArray, LngArray ) ;
        for (i = 0, j = 10; i < 6; i++, j--)
            {
                (*IntArray)[i] = (*IntArray)[j] ;
                (*LngArray)[i] = (*LngArray)[j] ;
                (*SngArray)[i] = (*SngArray)[j] ;
                (*DblArray)[i] = (*DblArray)[j] ;
            }
     printf ("\nModified Array Values\n") ;
        BTest ( IntArray, SngArray, DblArray, LngArray ) ;
        printf ("\nModified Last Array Elements\n") ;
        (*IntArray) [10] = (int)    3 ;
        (*SngArray) [10] = (float)  4.45 ;
        (*DblArray) [10] = (double) 30.303 ;
        (*LngArray) [10] = (long)   445 ;
    }

Program Output
==============

 Original Array Values

  0             0             0             0
  1             .5            1.5           1
  2             1             3             4
  3             1.5           4.5           9
  4             2             6             16
  5             2.5           7.5           25
  6             3             9             36
  7             3.5           10.5          49
  8             4             12            64
  9             4.5           13.5          81
  10            5             15            100

 Modified Array Values

  10            5             15            100
  9             4.5           13.5          81
  8             4             12            64
  7             3.5           10.5          49
  6             3             9             36
  5             2.5           7.5           25
  6             3             9             36
  7             3.5           10.5          49
  8             4             12            64
  9             4.5           13.5          81
  10            5             15            100

 Modified Last Array Elements

  3             4.45          30.303        445

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.