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 "How to Pass Parameters between Basic and C." 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).
- If you enter the libraries on the link line, then the Basic libraries must precede all others.
PASSING NUMERIC VARIABLES FROM Basic TO C BY NEAR REFERENCE
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
#include <stdio.h> void NumericNear(int *a, long *b, float *c, double *d) { printf("INTEGER %d\n", *a); printf("LONG %ld\n", *b); printf("FLOAT %f\n", *c); printf("DOUBLE %lf\n", *d);
}
Output
INTEGER 32767
LONG 32769 FLOAT 123.311996 DOUBLE 129381.333000
PASSING NUMERIC VARIABLES BETWEEN Basic AND C BY FAR REFERENCE
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
#include <stdio.h> void NumericFar(int far *a, long far *b, float far *c, double far *d)
{
printf("INTEGER %d\n", *a); printf("LONG %ld\n", *b); printf("FLOAT %f\n", *c); printf("DOUBLE %lf\n", *d); }
Output
INTEGER 32767
LONG 32769 FLOAT 123.311996 DOUBLE 129381.333000
PASSING NUMERIC VARIABLES FROM Basic TO C BY VALUE
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
#include <stdio.h>
struct struct_int {
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("INTEGER %d\n", a.x); printf("LONG %ld\n", b.x); printf("FLOAT %f\n", c.x); printf("DOUBLE %lf\n", d.x); }
Output
INTEGER 32767
LONG 32769 FLOAT 123.311996 DOUBLE 129381.333000
PASSING A C CHAR TO Basic
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
#include <stdio.h>
struct character {
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
PASSING A Basic VARIABLE-LENGTH STRING TO C BY NEAR REFERENCE
Basic Program
DECLARE SUB StringNear CDECL (_
BYVAL p1o AS INTEGER,_ p3 AS INTEGER) CLS
a$ = "This is a test" + CHR$(0) CALL StringNear(SADD(a$), LEN(a$)) END
C Routine
#include <stdio.h> void StringNear(char *a, int *len) { int i; printf("The string is : %s \n\n",a); printf(" Index Value Character\n"); for (i=0;i < *len; i++) { printf(" %2d %3d %c\n",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
PASSING A Basic VARIABLE-LENGTH STRING TO C BY FAR REFERENCE
Basic Program
DECLARE SUB StringFar CDECL (_
BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER) CLS
a$ = "This is a test" + CHR$(0) CALL StringFar(SADD(a$), VARSEG(a$), LEN(a$)) END
C Routine
#include <stdio.h> void StringFar(char far *a, int *len) { int i; printf("The string is : %s \n\n",a); printf(" Index Value Character\n"); for (i=0;i < *len; i++) { printf(" %2d %3d %c\n", 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
PASSING A Basic STRING DESCRIPTOR TO C
Basic Program
DECLARE SUB StringNear CDECL (a$)
CLS array$ = "This is a test" + CHR$(0) CALL StringNear(array$) END
C Routine
#include <stdio.h>
struct struct_string {
int length; char *address;
};
void StringNear(struct struct_string *string) { int i; printf("The string is : %s\n\n",string->address); printf(" Index Value Character\n"); for (i=0;i < string->length; i++) { printf(" %2d %3d %c\n", 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
PASSING A Basic FIXED-LENGTH STRING TO C BY NEAR REFERENCE
Basic Program
DECLARE SUB StringNear CDECL (_
BYVAL p1o AS INTEGER,_ p3 AS INTEGER)
DIM a AS STRING * 15
CLS a = "This is a test" + CHR$(0) CALL StringNear(VARPTR(a), LEN(a)) END
C Routine
#include <stdio.h> void StringNear(char *a, int *len) { int i; printf("The string is : %s \n\n",a); printf(" Index Value Character\n"); for (i=0;i < *len; i++) { printf(" %2d %3d %c\n", 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
PASSING A Basic FIXED-LENGTH STRING TO C BY FAR REFERENCE
Basic Program
DECLARE SUB StringFar CDECL (_
BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER)
DIM a AS STRING * 15
CLS a = "This is a test" + CHR$(0) CALL StringFar(VARPTR(a), VARSEG(a), LEN(a)) END
C Routine
#include <stdio.h> void StringFar(char far *a, int *len) { int i; printf("The string is : %s \n\n", array); printf(" Index Value Character\n"); for (i=0;i < *len; i++) { printf(" %2d %3d %c\n", 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
PASSING A STRING FROM C TO Basic
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
#include <string.h>
struct stringdesc {
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, "This is the string"); strcpy(thesecondstring, "This is the second string"); bassub(std, thesecondstring);
}
Output
This is the string
18
This is the second string
26
PASSING A Basic USER-DEFINED TYPE TO C BY NEAR REFERENCE
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
#include <stdio.h>
struct record {
int a; char b[20]; float c;
};
void TypeReference(struct record *element) { printf("Record.A = %d\n", element->a); printf("Record.B = %s\n", element->b); printf("Record.C = %f\n", element->c);
}
Output
Record.A = 128 Record.B = 02-02-1988 Record.C = 39.599998
PASSING A Basic USER-DEFINED TYPE TO C BY FAR REFERENCE
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
#include <stdio.h>
struct record {
int a; char b[20]; float c;
};
void TypeReference(struct record *element) { printf("Record.A = %d\n", element->a); printf("Record.B = %s\n", element->b); printf("Record.C = %f\n", element->c);
}
Output
Record.A = 128 Record.B = 02-02-1988 Record.C = 39.599998
PASSING A Basic INTEGER ARRAY TO C BY FAR REFERENCE
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$ = "": WEND
PRINT "Back in Basic"
FOR i = 1 TO 10
PRINT i, array(i)
NEXT i
END
C Routine
#include <stdio.h> void IntArray (int far *array) { int i; printf("Index Value\n"); for (i=0; i < 11; i++) { printf(" %d %d\n", 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
PASSING A Basic ARRAY OF LONG INTEGERS TO C BY FAR REFERENCE
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 "Back in Basic"
FOR i = 1 TO 10
PRINT i, array(i)
NEXT i
END
C Routine
#include <stdio.h> void LongArray(long far *array) { int i; printf("Index Value\n"); for (i=0; i < 11; i++) { printf(" %d %ld\n", 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
PASSING A Basic SINGLE-PRECISION ARRAY TO C BY FAR REFERENCE
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 "Back in Basic"
FOR i = 1 TO 10
PRINT i, array(i)
NEXT i
END
C Routine
#include <stdio.h> void FloatArray(float far *array) { int i; printf("Index Value\n"); for (i=0; i < 11; i++) { printf(" %d %f\n", 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
PASSING A Basic DOUBLE-PRECISION ARRAY TO C BY FAR REFERENCE
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 "Back in Basic"
FOR i = 1 TO 10
PRINT i, array(i)
NEXT i
END
C Routine
#include <stdio.h> void DoubleArray(double far *array) { int i; printf("Index Value\n"); for (i=0; i < 11; i++) { printf(" %d %lf\n", 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
PASSING A Basic ARRAY OF VARIABLE-LENGTH STRINGS TO C
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
#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(" Index Length String\n"); for (i=0; i < 10; i++) { printf(" %2d %3d %s\n", 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
PASSING A Basic ARRAY OF FIXED-LENGTH STRINGS TO C
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
#include <stdio.h> void StringFar(int *len, int *num, char far *array) { int i; printf("The string length is : %d \n\n",*len); printf("The number of elements is : %d \n\n",*num); printf(" Index String\n"); for (i=0; i < *num; i++) { printf(" %2d %s\n", 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
PASSING A Basic ARRAY OF USER-DEFINED TYPE TO C
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) + ". " + DATE$ + CHR$(0) element(I).c = 39.6 * I
NEXT I
CALL TypeArray(VARPTR(element(0)), VARSEG(element(0))) END
C Routine
#include <stdio.h>
struct record {
int a; char b[20]; float c;
};
void TypeArray(struct record far *element) { int i; for (i=0; i<3; i++) { printf("Record[%d].A = %d\n", i, element->a); printf("Record[%d].B = %s\n", i, element->b); printf("Record[%d].C = %f\n", i, element->c); printf("\n"); 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
PASSING A Basic TWO-DIMENSIONAL INTEGER ARRAY TO C BY FAR REFERENCE
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
#include <stdio.h>
struct two_int_array {
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(" %3d ",x->a[i][j]); }; printf("\n"); }; }
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
PASSING A Basic TWO-DIMENSIONAL VARIABLE-LENGTH STRING ARRAY TO C
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
#include <stdio.h>
struct struct_string {
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(" %s ",array->x[i][j].address); }; printf("\n"); };
}
Output
AAAAA BBBBB CCCCC DDDDD EEEEE BBBBB CCCCC DDDDD EEEEE FFFFF
PASSING A COMMON BLOCK FROM Basic TO C BY FAR REFERENCE
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 = "DATE : " + DATE$ + CHR$(0) element3 = 309.03 CALL RCommon(VARPTR(element1), VARSEG(element1)) END
C Routine
#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("Element1 = %d\n", pointer->a); printf("Element2 = %s\n", pointer->b); printf("Element3 = %f\n", pointer->c);
}
Output
Element1 = 23 Element2 = DATE : 02-02-1988 Element3 = 309.029999
PASSING A FIXED-LENGTH STRING FROM C TO Basic BY FAR REFERENCE
Basic Program
DECLARE SUB StringFar CDECL (_
BYVAL p1o AS INTEGER,_ BYVAL p1s AS INTEGER,_ p3 AS INTEGER)
DIM array AS STRING * 15
CLS array = "This is a test" + CHR$(0) CALL StringFar(VARPTR(array), VARSEG(array), LEN(array)) LOCATE 20,20 PRINT array END
C Routine
#include <stdio.h> void StringFar(char far *a, int *len) { int i; printf("The string is : %s \n\n",a); printf(" Index Value Character\n"); for (i = 0;i < *len; i++) { printf(" %2d %3d %c\n", 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 @@@@
C FUNCTIONS RETURNING NUMERICS TO Basic
Basic Program
DECLARE FUNCTION cintfunc% CDECL () DECLARE FUNCTION clongfunc& CDECL () DECLARE FUNCTION cdoublefunc# CDECL ()
PRINT "Integer: "; cintfunc
PRINT "Long : "; clongfunc
PRINT "Double : "; 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.
A Basic FUNCTION RETURNING A STRING TO C
Basic Program
DECLARE SUB CSUB CDECL () CALL CSUB END FUNCTION basvarfunc$(dummy%)
basvarfunc$ = "This is the string"
END FUNCTION
C Routine
#include <stdio.h>
struct stringdesc {
int length; char *string;
};
extern struct stringdesc * pascal basvarfunc(int *dummy);
struct stringdesc *std;
void csub() { int i; std = basvarfunc(0); printf("Length of string: %2d\r\n", std->length); for(i = 0; i < std->length; i++) printf("%c", std->string[i]); printf("\r\n");
}
Output
Length of string: 18 This is the string
A C FUNCTION RETURNING A STRING TO Basic
Basic Program
DECLARE FUNCTION CFUNC$ CDECL () a$ = CFUNC$ PRINT a$ PRINT len(a$)
C Routine
#include <string.h>
struct stringdesc {
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, "This is the string"); std->string = thestring; return(std); // return pointer to string descriptor }
Output
This is the string 8
Additional reference words: QuickBas BasicCom Last reviewed: January 12, 1995 |