Microsoft KB Archive/71274

= Microsoft Knowledge Base =

How to Pass Parameters Between Basic and C (Part 2 of 2)
Last reviewed: January 12, 1995

Article ID: Q71274

The information in this article applies to:


 * Microsoft Basic Professional Development System (PDS) for MS-DOS, versions 7.0 and 7.1
 * Microsoft Basic Compiler versions 6.00 and 6.00b for MS-DOS and MS OS/2
 * Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5
 * Standard and Professional Editions of Microsoft Visual Basic for MS-DOS, version 1.0
 * Microsoft C Optimizing Compiler versions 5.00, 5.10, and 6.00 for MS-DOS and MS OS/2
 * Microsoft QuickC versions 1.00, 1.01, 2.00, 2.01, and 2.50 for MS-DOS

SUMMARY
This article contains Part 2 of 2 of the complete text of &quot;How to Pass Parameters between Basic and C.&quot; To obtain Part 1 of 2, please see the following article in the Microsoft Knowledge Base:

ARTICLE-ID: Q50062

TITLE    : How to Pass Parameters Between Basic and C (Part 1 of 2)

MORE INFORMATION
This is part 2 of 2:

COMPILING AND LINKING THE SAMPLE PROGRAMS
Following the appendix is a series of examples that demonstrate the interlanguage calling capabilities between Basic and C.

When compiling the sample Basic programs, you can compile with or without the /O (BCOM stand-alone library) option. The following uses the BCOM library to produce a stand-alone Basic program:

BC /O Basicprogramname; The following uses the BRUN library, so that the compiled program needs the BRUN run-time library on disk when it is executed:

BC Basicprogramname When compiling the sample C programs, one of the following compile lines should be used:

Compile Line              Used For

CL /c /AM Cprogramname;   C 5.00 and C 5.10

QCL /c /AM Cprogramname;  QuickC NOTE: For convenience, the medium memory model is used for the C programs. If the large memory model were used instead (/AL instead of /AM), all pointers would have to be explicitly defined as near.

To link the programs, use the following link line:

LINK /NOE Basicprogramname Cprogramname;

APPENDIX: COMMON PITFALLS
The following common pitfalls are all explained in more detail in the main text. Use this appendix as a checklist when you encounter problems while doing mixed-language programming.

  Make certain the version numbers of the two languages are compatible. The following table specifies which versions of Microsoft Basic can be linked with specific versions of Microsoft C or QuickC: Basic QuickBasic   Compiler  <->    C       QuickC --     ---    -       --

4.00           --      <->    5.00    1.00        --          6.00      <->    5.10    1.01      4.00b    or   6.00b     <->    5.10    1.01 4.50    or   7.00      <->    5.10    2.00 or 2.01 --         7.10      <->    6.00    2.50  Make certain that a C routine is declared with CDECL in Basic or that in C the pascal directive is used when defining the procedure. This ensures the same calling convention is being used. Make sure that the graphic libraries are not included in the C libraries. If the graphic libraries are included, duplicate definition errors will occur. Use the /NOE switch when linking to avoid duplicate definition errors. If duplicate definition errors still occur, also use the /NOD switch when linking. Watch for incompatible C functions such as system and getenv.  When passing strings to C, check for two things: a. If a C function will use the string, it should be NULL (CHR$(0)) terminated. b. SADD should be used instead of VARPTR to pass the actual address of the string. VARPTR returns the offset to the string descriptor, not to the string itself.  The C routine should be compiled in the medium or large memory model. If the large memory model is used, then all pointers to Basic variables must be explicitly defined as near. When using VARSEG, VARPTR, or SADD to pass addresses to C, it is important to check the function definition. Since Basic normally passes all parameters by reference, any parameter that is an address should be declared using BYVAL. If BYVAL is not used, then Basic creates a temporary variable to hold the address and then passes a pointer to this variable (in effect, Basic passes a pointer to a pointer).</li> If you enter the libraries on the link line, then the Basic libraries must precede all others.</li></ol>

Basic Program
DECLARE SUB NumericNear CDECL (a%,b&,c!,d#)

a% = 32767 b& = 32769 c! = 123.312 d# = 129381.333#

CLS CALL NumericNear(a%, b&, c!, d#) END

C Routine

 * 1) include <stdio.h>

void NumericNear(int *a, long *b, float *c, double *d) { printf(&quot;INTEGER %d\n&quot;, *a); printf(&quot;LONG   %ld\n&quot;, *b); printf(&quot;FLOAT  %f\n&quot;, *c); printf(&quot;DOUBLE %lf\n&quot;, *d); }

Output
INTEGER 32767

LONG    32769 FLOAT   123.311996 DOUBLE  129381.333000

Basic Program
DECLARE SUB NumericFar CDECL (_

BYVAL p1o AS INTEGER, BYVAL p1s AS INTEGER,_ BYVAL p2o AS INTEGER, BYVAL p2s AS INTEGER,_ BYVAL p3o AS INTEGER, BYVAL p3s AS INTEGER,_ BYVAL p4o AS INTEGER, BYVAL p4s AS INTEGER) a% = 32767 b& = 32769 c! = 123.312 d# = 129381.333#

CLS CALL NumericFar(VARPTR(a%), VARSEG(a%),_

VARPTR(b&), VARSEG(b&),_ VARPTR(c!), VARSEG(c!),_ VARPTR(d#), VARSEG(d#)) END

C Routine
void NumericFar(int far *a, long far *b, float far *c, double far *d) {
 * 1) include <stdio.h>

printf(&quot;INTEGER %d\n&quot;, *a); printf(&quot;LONG    %ld\n&quot;, *b); printf(&quot;FLOAT   %f\n&quot;, *c); printf(&quot;DOUBLE  %lf\n&quot;, *d); }

Output
INTEGER 32767

LONG    32769 FLOAT   123.311996 DOUBLE  129381.333000

Basic Program
DECLARE SUB NumericValue CDECL (_

BYVAL p1 AS INTEGER,_ BYVAL p2 AS LONG,_ BYVAL p3 AS SINGLE,_ BYVAL p4 AS DOUBLE) a% = 32767 b& = 32769 c! = 123.312 d# = 129381.333#

CLS CALL NumericValue(a%, b&, c!, d#) END

C Routine
struct struct_int {
 * 1) include <stdio.h>

int x; };

struct struct_long {

long x; };

struct struct_float {

float x; };

struct struct_double {

double x; };

void NumericValue(struct struct_int a, struct struct_long b,                 struct struct_float c, struct struct_double d) { printf(&quot;INTEGER %d\n&quot;, a.x); printf(&quot;LONG    %ld\n&quot;, b.x); printf(&quot;FLOAT   %f\n&quot;, c.x); printf(&quot;DOUBLE  %lf\n&quot;, d.x); }

Output
INTEGER 32767

LONG    32769 FLOAT   123.311996 DOUBLE  129381.333000

Basic Program
DECLARE SUB CSUB CDECL

TYPE chartype

character AS STRING *1 END TYPE

CALL CSUB

END

SUB BASSUB(cchar AS chartype)

PRINT cchar.character PRINT LEN(cchar.character) END SUB

C Routine
struct character {
 * 1) include <stdio.h>

char thechar; };

extern void pascal bassub(struct character *baschar);

struct character *c_char;

void csub { c_char->thechar = 'A'; bassub(c_char); }

Output
A

1

Basic Program
DECLARE SUB StringNear CDECL (_

BYVAL p1o AS INTEGER,_ p3 AS INTEGER)

CLS a$ = &quot;This is a test&quot; + CHR$(0) CALL StringNear(SADD(a$), LEN(a$)) END

C Routine

 * 1) include <stdio.h>

void StringNear(char *a, int *len) { int i;  printf(&quot;The string is : %s \n\n&quot;,a); printf(&quot; Index      Value       Character\n&quot;);

for (i=0;i < *len; i++) { printf(&quot; %2d          %3d            %c\n&quot;,i,a[i],a[i]); }; }

Output
The string is : This is a test

Index      Value       Character 0          84            T   1          104            h   2          105            i   3          115            s   4           32 5         105            i   6          115            s   7           32 8          97            a   9           32 10         116            t  11          101            e  12          115            s  13          116            t  14            0

Basic Program
DECLARE SUB StringFar CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER)

CLS a$ = &quot;This is a test&quot; + CHR$(0) CALL StringFar(SADD(a$), VARSEG(a$), LEN(a$)) END

C Routine

 * 1) include <stdio.h>

void StringFar(char far *a, int *len) { int i;  printf(&quot;The string is : %s \n\n&quot;,a); printf(&quot; Index      Value       Character\n&quot;);

for (i=0;i < *len; i++) { printf(&quot; %2d          %3d            %c\n&quot;, i, a[i], a[i]); }; }

Output
The string is : This is a test

Index      Value       Character 0          84            T   1          104            h   2          105            i   3          115            s   4           32 5         105            i   6          115            s   7           32 8          97            a   9           32 10         116            t  11          101            e  12          115            s  13          116            t  14            0

Basic Program
DECLARE SUB StringNear CDECL (a$)

CLS array$ = &quot;This is a test&quot; + CHR$(0) CALL StringNear(array$) END

C Routine
struct struct_string {
 * 1) include <stdio.h>

int length; char *address; };

void StringNear(struct struct_string *string) { int i;  printf(&quot;The string is : %s\n\n&quot;,string->address); printf(&quot; Index      Value       Character\n&quot;);

for (i=0;i < string->length; i++) { printf(&quot; %2d          %3d            %c\n&quot;, i,             string->address[i], string->address[i]); }; }

Output
The string is : This is a test

Index      Value       Character 0          84            T   1          104            h   2          105            i   3          115            s   4           32 5         105            i   6          115            s   7           32 8          97            a   9           32 10         116            t  11          101            e  12          115            s  13          116            t  14            0

Basic Program
DECLARE SUB StringNear CDECL (_

BYVAL p1o AS INTEGER,_ p3 AS INTEGER) DIM a AS STRING * 15

CLS a = &quot;This is a test&quot; + CHR$(0) CALL StringNear(VARPTR(a), LEN(a)) END

C Routine

 * 1) include <stdio.h>

void StringNear(char *a, int *len) { int i;  printf(&quot;The string is : %s \n\n&quot;,a); printf(&quot; Index      Value       Character\n&quot;);

for (i=0;i < *len; i++) { printf(&quot; %2d          %3d            %c\n&quot;, i, a[i], a[i]); }; }

Output
The string is : This is a test

Index      Value       Character 0          84            T   1          104            h   2          105            i   3          115            s   4           32 5         105            i   6          115            s   7           32 8          97            a   9           32 10         116            t  11          101            e  12          115            s  13          116            t  14            0

Basic Program
DECLARE SUB StringFar CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER) DIM a AS STRING * 15

CLS a = &quot;This is a test&quot; + CHR$(0) CALL StringFar(VARPTR(a), VARSEG(a), LEN(a)) END

C Routine

 * 1) include <stdio.h>

void StringFar(char far *a, int *len) { int i;  printf(&quot;The string is : %s \n\n&quot;, array); printf(&quot; Index      Value       Character\n&quot;);

for (i=0;i < *len; i++) { printf(&quot; %2d          %3d            %c\n&quot;, i, a[i], a[i]); }; }

Output
The string is : This is a test

Index      Value       Character 0          84            T   1          104            h   2          105            i   3          115            s   4           32 5         105            i   6          115            s   7           32 8          97            a   9           32 10         116            t  11          101            e  12          115            s  13          116            t  14            0

Basic Program
DECLARE SUB CSUB CDECL

TYPE fixstringtype

B AS STRING * 26 END TYPE

CALL CSUB

END

SUB BASSUB(A$, B AS fixstringtype)

PRINT A$  PRINT LEN(A$) PRINT B.B  PRINT LEN(B.B) END SUB

C Routine
struct stringdesc {
 * 1) include <string.h>

int length; char *string; };

extern void pascal bassub(struct stringdesc *basstring,

char *basfixstring); struct stringdesc *std;

char thesecondstring[26];

void csub { std->length = 18; strcpy(std->string, &quot;This is the string&quot;); strcpy(thesecondstring, &quot;This is the second string&quot;); bassub(std, thesecondstring); }

Output
This is the string

18 This is the second string

26

Basic Program
TYPE record

a AS INTEGER b AS STRING * 20 c AS SINGLE END TYPE

DECLARE SUB TypeReference CDECL (p1 AS record)

CLS DIM element AS record element.a = 128 element.b = DATE$ + CHR$(0) element.c = 39.6 CALL TypeReference(element) END

C Routine
struct record {
 * 1) include <stdio.h>

int a;  char b[20]; float c; };

void TypeReference(struct record *element) { printf(&quot;Record.A = %d\n&quot;, element->a); printf(&quot;Record.B = %s\n&quot;, element->b); printf(&quot;Record.C = %f\n&quot;, element->c); }

Output
Record.A = 128 Record.B = 02-02-1988 Record.C = 39.599998

Basic Program
TYPE record

a AS INTEGER b AS STRING * 20 c AS SINGLE END TYPE

DECLARE SUB TypeReference CDECL (BYVAL p1o AS INTEGER, _

BYVAL p1s AS INTEGER)

CLS DIM element AS record element.a = 128 element.b = DATE$ + CHR$(0) element.c = 39.6 CALL TypeReference(VARPTR(element), VARSEG(element)) END

C Routine
struct record {
 * 1) include <stdio.h>

int a;  char b[20]; float c; };

void TypeReference(struct record *element) { printf(&quot;Record.A = %d\n&quot;, element->a); printf(&quot;Record.B = %s\n&quot;, element->b); printf(&quot;Record.C = %f\n&quot;, element->c); }

Output
Record.A = 128 Record.B = 02-02-1988 Record.C = 39.599998

Basic Program
DECLARE SUB IntArray CDECL (_

BYVAL p1 AS INTEGER,_ BYVAL p2 AS INTEGER) DEFINT A-Z DIM i AS INTEGER DIM array(10) AS INTEGER

CLS

FOR i = 1 TO 10

array(i) = i NEXT i

'Array must be a FAR pointer, so offset and segment must be passed: CALL IntArray(VARPTR(array(0)), VARSEG(array(0))) LOCATE 15, 1

WHILE INKEY$ = &quot;&quot;: WEND

PRINT &quot;Back in Basic&quot;

FOR i = 1 TO 10

PRINT i, array(i) NEXT i

END

C Routine

 * 1) include <stdio.h>

void IntArray (int far *array) { int i;

printf(&quot;Index        Value\n&quot;);

for (i=0; i < 11; i++) { printf(&quot; %d          %d\n&quot;, i, array[i]); array[i] = array[i] + 100; }; }

Output
Index     Value 0         0 1          1 2          2 3          3 4          4 5          5 6          6 7          7 8          8 9          9 10         10 Back in Basic

1            101 2             102 3             103 4             104 5             105 6             106 7             107 8             108 9             109 10            110

Basic Program
DECLARE SUB LongArray CDECL (_

BYVAL p1 AS INTEGER,_ BYVAL p2 AS INTEGER) DEFINT A-Z DIM i AS LONG DIM array(10) AS LONG

CLS

FOR i = 1 TO 10

array(i) = i + 100 NEXT i

'Array must be a FAR pointer, so offset and segment must be passed: CALL LongArray(VARPTR(array(0)), VARSEG(array(0))) LOCATE 15, 1 PRINT &quot;Back in Basic&quot;

FOR i = 1 TO 10

PRINT i, array(i) NEXT i

END

C Routine

 * 1) include <stdio.h>

void LongArray(long far *array) { int i;  printf(&quot;Index         Value\n&quot;);

for (i=0; i < 11; i++) { printf(&quot; %d          %ld\n&quot;, i, array[i]); array[i] = array[i] + 100; }; }

Output
Index        Value 0         0  1          101  2          102  3          103  4          104  5          105  6          106  7          107  8          108  9          109  10          110 Back in Basic

1            201 2             202 3             203 4             204 5             205 6             206 7             207 8             208 9             209 10            210

Basic Program
DECLARE SUB FloatArray CDECL (_

BYVAL p1 AS INTEGER,_ BYVAL p2 AS INTEGER) DEFINT A-Z DIM i AS SINGLE DIM array(10) AS SINGLE

CLS

FOR i = 1 TO 10

array(i) = i + 100 NEXT i

'Array must be a FAR pointer, so offset and segment must be passed: CALL FloatArray(VARPTR(array(0)), VARSEG(array(0))) LOCATE 15, 1 PRINT &quot;Back in Basic&quot;

FOR i = 1 TO 10

PRINT i, array(i) NEXT i

END

C Routine

 * 1) include <stdio.h>

void FloatArray(float far *array) { int i;

printf(&quot;Index        Value\n&quot;);

for (i=0; i < 11; i++) { printf(&quot; %d          %f\n&quot;, i, array[i]); array[i] = array[i]+100; }; }

Output
Index        Value 0         0.000000 1          101.000000 2          102.000000 3          103.000000 4          104.000000 5          105.000000 6          106.000000 7          107.000000 8          108.000000 9          109.000000 10          110.000000 Back in Basic

1            201 2             202 3             203 4             204 5             205 6             206 7             207 8             208 9             209 10            210

Basic Program
DECLARE SUB DoubleArray CDECL (_

BYVAL p1 AS INTEGER,_ BYVAL p2 AS INTEGER) DEFINT A-Z DIM i AS DOUBLE DIM array(10) AS DOUBLE

CLS

FOR i = 1 TO 10

array(i) = i + 100 NEXT i

'Array must be a FAR pointer, so offset and segment must be passed: CALL DoubleArray(VARPTR(array(0)), VARSEG(array(0))) LOCATE 15, 1 PRINT &quot;Back in Basic&quot;

FOR i = 1 TO 10

PRINT i, array(i) NEXT i

END

C Routine

 * 1) include <stdio.h>

void DoubleArray(double far *array) { int i;

printf(&quot;Index        Value\n&quot;);

for (i=0; i < 11; i++) { printf(&quot; %d          %lf\n&quot;, i, array[i]); array[i] = array[i] + 100; }; }

Output
Index        Value 0         0.000000 1          101.000000 2          102.000000 3          103.000000 4          104.000000 5          105.000000 6          106.000000 7          107.000000 8          108.000000 9          109.000000 10          110.000000 Back in Basic

1            201 2             202 3             203 4             204 5             205 6             206 7             207 8             208 9             209 10            210

Basic Program
DECLARE SUB StringArray CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p2s AS INTEGER) DIM array$(10)

CLS

FOR i = 0 TO 10

array$(i) = STRING$(9, 65 + i) + CHR$(0) NEXT i

CALL StringArray(VARPTR(array$(0)), VARSEG(array$(0))) END

C Routine

 * 1) include <stdio.h>

struct struct_string {  // structure that looks like a   int length;           // string descriptor char *address; };

void StringArray(struct struct_string far *string) { int i;

printf(&quot; Index Length    String\n&quot;);

for (i=0; i < 10; i++) { printf(&quot; %2d     %3d     %s\n&quot;, i, string->length,             string->address); string++; }; }

Output
Index Length    String 0     10     AAAAAAAAA 1     10     BBBBBBBBB 2     10     CCCCCCCCC 3     10     DDDDDDDDD 4     10     EEEEEEEEE 5     10     FFFFFFFFF 6     10     GGGGGGGGG 7     10     HHHHHHHHH 8     10     IIIIIIIII 9     10     JJJJJJJJJ

Basic Program
DECLARE SUB StringFar CDECL (_

length%,_ num%,_ BYVAL p3o AS INTEGER,_ BYVAL p3s AS INTEGER) DIM array(10) AS STRING * 10

CLS length% = 10 num% = 3

FOR i = 0 TO 10

array(i) = STRING$(9, 65 + i) + CHR$(0) NEXT i

CALL StringFar(length%, num%, VARPTR(array(0)), VARSEG(array(0))) END

C Routine

 * 1) include <stdio.h>

void StringFar(int *len, int *num, char far *array) { int i;  printf(&quot;The string length is : %d \n\n&quot;,*len); printf(&quot;The number of elements is : %d \n\n&quot;,*num); printf(&quot; Index       String\n&quot;); for (i=0; i < *num; i++) { printf(&quot; %2d         %s\n&quot;, i, array); array=array+*len; }; }

Output
The string length is : 10

The number of elements is : 3

Index       String 0        AAAAAAAAA 1        BBBBBBBBB 2        CCCCCCCCC

Basic Program
TYPE record

a AS INTEGER b AS STRING * 20 c AS SINGLE END TYPE

DECLARE SUB TypeArray CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER) DIM element(10) AS record

CLS

FOR I = 0 TO 10

element(I).a = 128 + I  element(I).b = STR$(I) + &quot;. &quot; + DATE$ + CHR$(0) element(I).c = 39.6 * I NEXT I

CALL TypeArray(VARPTR(element(0)), VARSEG(element(0))) END

C Routine
struct record {
 * 1) include <stdio.h>

int a;  char b[20]; float c; };

void TypeArray(struct record far *element) { int i;

for (i=0; i<3; i++) { printf(&quot;Record[%d].A = %d\n&quot;, i, element->a); printf(&quot;Record[%d].B = %s\n&quot;, i, element->b); printf(&quot;Record[%d].C = %f\n&quot;, i, element->c); printf(&quot;\n&quot;); element++; };

}

Output
Record[0].A = 128 Record[0].B = 0. 02-02-1988 Record[0].C = 0.000000

Record[1].A = 129 Record[1].B = 1. 02-02-1988 Record[1].C = 39.599998

Record[2].A = 130 Record[2].B = 2. 02-02-1988 Record[2].C = 79.199997

Basic Program
DECLARE SUB TwoIntArray CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER) DIM x(4, 4) AS INTEGER

CLS

FOR i = 0 TO 4

FOR j = 0 TO 4 x(i, j) = i * j  NEXT j NEXT i

CALL TwoIntArray(VARPTR(x(0, 0)), VARSEG(x(0, 0))) END

C Routine
struct two_int_array {
 * 1) include <stdio.h>

int a[5][5]; };

void TwoIntArray(struct two_int_array far *x) { int i,j;

for (i = 0; i < 5; i++) {

for (j = 0; j < 5; j++) { printf(&quot; %3d   &quot;,x->a[i][j]); };

printf(&quot;\n&quot;); };

}

Output
0      0       0       0       0    0       1       2       3       4    0       2       4       6       8    0       3       6       9      12    0       4       8      12      16

Basic Program
DECLARE SUB TwoStringArray CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER) DIM array$(4, 1)

CLS

FOR i = 0 TO 1

FOR j = 0 TO 4 array$(j, i) = STRING$(5, 65 + (i + j)) + CHR$(0) NEXT j NEXT i

CALL TwoStringArray(VARPTR(array$(0, 0)), VARSEG(array$(0, 0))) END

C Routine
struct struct_string {
 * 1) include <stdio.h>

int length; char *address; };

struct string_array{

struct struct_string x[2][5]; };

void TwoStringArray(struct string_array far *array) { int i,j;

for (i = 0; i < 2; i++) {

for(j = 0;j < 5; j++) { printf(&quot; %s  &quot;,array->x[i][j].address); };

printf(&quot;\n&quot;); }; }

Output
AAAAA   BBBBB    CCCCC    DDDDD    EEEEE BBBBB   CCCCC    DDDDD    EEEEE    FFFFF

Basic Program
DECLARE SUB RCommon CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER) COMMON SHARED element1 AS INTEGER, element2 AS STRING * 20,_

element3 AS SINGLE element1 = 23 element2 = &quot;DATE : &quot; + DATE$ + CHR$(0) element3 = 309.03 CALL RCommon(VARPTR(element1), VARSEG(element1)) END

C Routine

 * 1) include <stdio.h>

struct common_block {  // structure that looks like the Basic int a;              // common block char b[20]; float c; };

void RCommon(struct common_block far *pointer) { printf(&quot;Element1 = %d\n&quot;, pointer->a); printf(&quot;Element2 = %s\n&quot;, pointer->b); printf(&quot;Element3 = %f\n&quot;, pointer->c); }

Output
Element1 = 23 Element2 = DATE : 02-02-1988 Element3 = 309.029999

Basic Program
DECLARE SUB StringFar CDECL (_

BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER) DIM array AS STRING * 15

CLS array = &quot;This is a test&quot; + CHR$(0) CALL StringFar(VARPTR(array), VARSEG(array), LEN(array)) LOCATE 20,20 PRINT array END

C Routine

 * 1) include <stdio.h>

void StringFar(char far *a, int *len) { int i;

printf(&quot;The string is : %s \n\n&quot;,a); printf(&quot; Index      Value       Character\n&quot;);

for (i = 0;i < *len; i++) { printf(&quot; %2d       %3d      %c\n&quot;, i, a[i], a[i]); };

/* This loop writes over the end of the string */ for (i = 10; i < *len; i++) { a[i] = 64;   // ASCII value for '@' }; }

Output
The string is : This is a test

Index      Value       Character 0          84          T 1          104          h 2          105          i 3          115          s 4           32 5         105          i 6          115          s 7           32 8                      a 9           32 10         116          t 11          101          e 12          115          s 13          116          t

This is a @@@@

Basic Program
DECLARE FUNCTION cintfunc% CDECL DECLARE FUNCTION clongfunc& CDECL  DECLARE FUNCTION cdoublefunc# CDECL

PRINT &quot;Integer: &quot;; cintfunc

PRINT &quot;Long  : &quot;; clongfunc PRINT &quot;Double : &quot;; cdoublefunc

C Routines
int cintfunc(void) { int theint = 32767; return(theint); }

long clongfunc(void) {

long thelong = 32769; return(thelong); }

double cdoublefunc(void) {

double thedouble = 129381.123; return(thedouble); }

Output
Integer: 32767 Long : 32769 Double : 129381.123

Note: It is not currently possible to have a C function return a SINGLE- precision number to Basic. Microsoft is researching this problem and will post new information as it becomes available.

Basic Program
DECLARE SUB CSUB CDECL CALL CSUB END FUNCTION basvarfunc$(dummy%)

basvarfunc$ = &quot;This is the string&quot; END FUNCTION

C Routine
struct stringdesc {
 * 1) include <stdio.h>

int length; char *string; };

extern struct stringdesc * pascal basvarfunc(int *dummy);

struct stringdesc *std;

void csub { int i;

std = basvarfunc(0); printf(&quot;Length of string: %2d\r\n&quot;, std->length);

for(i = 0; i < std->length; i++) printf(&quot;%c&quot;, std->string[i]);

printf(&quot;\r\n&quot;); }

Output
Length of string: 18 This is the string

Basic Program
DECLARE FUNCTION CFUNC$ CDECL a$ = CFUNC$ PRINT a$ PRINT len(a$)

C Routine
struct stringdesc {
 * 1) include <string.h>

int length;       // length of the string char *string;     // near pointer to the string }; struct stringdesc *std;

char thestring[18];     /* In the medium memory model this string will be in DGROUP - which is required for Basic   */ struct stringdesc *cfunc {

std->length = 18;     // length of the string strcpy(thestring, &quot;This is the string&quot;); std->string = thestring; return(std);          // return pointer to string descriptor }

Output
This is the string 8