home *** CD-ROM | disk | FTP | other *** search
- Date: 12-30-91 (19:53)
- From: HOWARD MENCHER
- Subj: MIXED LANGUAGE PROG -1-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 1
- ---------------------------------------------------------------------------
- --The following is a list of the versions needed for these routines:
-
- BASIC BASCOM 6.00+ QB 4.00+
- QUICK C 1.0 OR C 5.0
-
- --Some rules to follow:
-
- 1. Use the same math package for both languages (for example using the alt-
- ernate math package in BASCOM 6.00 requires the use of the alternate math
- package in C5.1).
- 2. Compile the C, FORTRAN, PASCAL, or MASM routine in the medium or large
- memory model.
- 3. The BASIC .OBJ file must be the first .OBJ in the LINK command.
- 4. LINK with the /NOE option.
- 5. Use the /NOD LINK option when using specific component libraries; these
- libraries must be specified on the library LINK line.
- 6. Use the /NOI LINK option when using routines of the same name, but in
- different cases (e.g. upper case vs. lower case- ASUB vs. aSub).
- 7. When passing a BASIC string descriptor to a routine DON'T try extending
- its length - a "String Space Corrupt" error will be received.
- 8. Both C and BASIC graphics can't be used at the same time; if your C
- libraries were built with graphics included, you will need to rebuild
- them or else multiple definition errors will occur.
- 9. Simplified segment directives are used in MASM, this is why MASM 5.00 is
- needed.
-
- --To use the executable (.EXE) program in CodeView:
- 1. Compile both BASIC and C, FORTRAN, MASM or PASCAL programs with the /ZI
- option.
- 2. LINK with the /CO option.
-
-
-
- Passing a FIXED LENGTH string to C by NEAR REFERENCE: BAS7.BAS/ C7.C
-
-
- DECLARE SUB StringNear CDECL (_
- BYVAL p1o AS INTEGER,_
- SEG p3 AS INTEGER)
-
- CLS
- DIM a AS STRING * 15
-
- a = "This is a test" + CHR$(0)
- CALL StringNear(VARPTR(a), LEN(a))
-
- END
-
-
-
- #include <stdio.h>
-
- void StringNear(a,len)
- char near *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]);
- };
- }
-
- <<<<< END PART 1 >>>>>
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 2 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
- Passing FIXED LENGTH String to C by FAR REFERENCE
-
-
- DECLARE SUB StringFar CDECL (_
- BYVAL p1o AS INTEGER,_
- BYVAL p1s AS INTEGER,_
- SEG p3 AS INTEGER)
-
- CLS
- DIM array AS STRING * 15
-
- a = "This is a test" + CHR$(0)
- CALL StringFar(VARPTR(a), VARSEG(a), LEN(a))
-
- END
-
-
-
- #include <stdio.h>
-
- void StringFar(a,len)
- 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]);
- };
- }
-
-
-
- Passing an arrray of VARIABLE LENGTH STRINGS: BAS15.BAS/ C15.C
-
-
- DECLARE SUB StringArray CDECL (_
- BYVAL p1o AS INTEGER,_
- BYVAL p2s AS INTEGER)
-
- CLS
- DIM array$(10)
- FOR i = 0 TO 10
- array$(i) = STRING$(9, 65 + i) + CHR$(0)
- NEXT i
-
- CALL StringArray(VARPTR(array$(0)), VARSEG(array$(0)))
-
- END
-
-
-
- #include <stdio.h>
-
- struct struct_string{ /* structure that looks like a */
- int length; /* string descriptor */
- char *address;
- };
-
- void StringArray(string)
- 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++;
- };
- }
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 3 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
- Passing an array of FIXED LENGTH STRINGS to C
-
-
- DECLARE SUB StringFar CDECL (_
- length%,_
- num%,_
- BYVAL p3o AS INTEGER,_
- BYVAL p3s AS INTEGER)
-
- CLS
- DIM array(10) AS STRING * 10
-
- 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
-
-
-
- #include <stdio.h>
-
- void StringFar(len,num,array)
- 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;
- };
- }
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 4 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
- Passing an array of USER DEFINED TYPES to C
-
-
- 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)
-
- CLS
- DIM element(10) AS record
-
- 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
-
-
-
-
-
-
- #include <stdio.h>
-
- struct record{
- int a;
- char b[20];
- float c;
- };
-
- void TypeArray(element)
- 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++;
- };
- }
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 5 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
- Passing BASIC 2-D array of VARIABLE LENGTH STRINGS
-
-
- DECLARE SUB TwoStringArray CDECL (_
- BYVAL p1o AS INTEGER,_
- BYVAL p1s AS INTEGER)
-
- CLS
-
- DIM array$(4, 4)
-
-
- FOR i = 0 TO 4
- FOR j = 0 TO 4
- array$(i, j) = STRING$(5, 65 + (i + j)) + CHR$(0)
- NEXT j
- NEXT i
-
- CALL TwoStringArray(VARPTR(array$(0, 0)),_
- VARSEG(array$(0, 0)))
-
- END
-
-
-
- #include <stdio.h>
-
- struct struct_string{
- int length;
- char *address;
- };
-
- struct string_array{
- struct struct_string x[5][5];
- };
-
-
- void TwoStringArray(array)
- struct string_array far *array;
-
- {
- int i,j;
- for (i=0;i < 5; i++)
- {
- for(j=0;j<5;j++)
- {
- printf(" %s ",array->x[i][j].address);
- };
- printf("\n");
- };
- }
-
- <<<< CONTINUED >>>>
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG 8 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
- /***************************************************************************
- * This example program should give you some help if you are trying to call
- * routines written for QuickBasic from C. In the process of converting
- * many of our QB stuff to C, we found that we didn't want to "give up" the
- * nice QB libraries we had.
- *
- * The problem is, the QB4 manual has some GROSS errors in it concerning
- * calling QB stuff from C. The example on page 310 (passing strings from
- * C to QB) is wrong. It should read:
- *
- * char cstr [] = "ABC";
- * struct dodo {
- * int sd_len; /* THESE ARE REVERSED IN MANUAL! */
- * char near *sd_addr; /* MUST DEFINE AS NEAR! */
- * } near str_des; /* best to define as near */
- *
- * (Page 307 clearly shows that the 2 byte length comes FIRST and the 2
- * byte address comes second - ever wonder if MS tests their examples?
- * Obviously they didn't in this case!)
- *
- *
- * Rather than going through all the ins-n-outs of why, (because frankly,
- * I'm not sure in some cases) I thought I'd simply provide a copy of a
- * program we wrote to call a routine written for QB. Note that the routine
- * is an Assembler routine WRITTEN FOR QB (i.e. it isn't written in QB).
- * This really doesn't make any difference, but it just lets you know that
- * if you have a bunch of commercial QB libraries, you should be able to use
- * them with C.
- *
- * The routine we are calling is called CRC. It's purpose is to calculate
- * a CRC on a record. (Thanks to Tom Hanlin and Wayne Hammerly of Hammerly
- * computers for providing this great routine for QB programmers!) In
- * QB you would call it as:
- *
- * CALL CRC(STRING$,HICRC%,LOCRC%)
- *
- * The string is what you pass to the subroutine, and the HICRC and LOCRC are
- * integers returned to you. We basically want to do the same thing from C.
- * The calling sequence in C is:
- *
- * crc(&str_des,&hicrc,&locrc);
- *
- * Note that you have to set the C program up to handle all this as shown in
- * the program.
- *
- * By the way, this program was compiled under large model and worked fine.
- * The only thing we wanted to do later was pass a string which had been
- * malloc'ed. This meant that it was no longer a NEAR string and could not
- * possibly be NEAR (i.e. defined within the function itself.) We had to
- * actually modify the assembler source to get this working since near stuff
- * passes only a two byte address (which is what QB routines expect.) So,
- * make SURE you define everything you are going to passing to QB routines
- * as NEAR or use medium or small model (where everything is near by default.)
- *
- * I am sorry that I could NOT include the CRC.OBJ module with this file.
- * I didn't because I didn't write it and it belongs to Tom Hanlin and Wayne
- * Hammerly. But, chances are, if you're reading this you are aware of the
- * ADVBAS series for QB. You can simply use the CRC module found in that
- * library. If you don't have ADVBAS (library for QB) I suggest you download
- * it from CompuServe or any of the thousands of BBS's which have it. By
- * the way, PROBAS (the commercial version of ADVBAS) also has CRC in it.
- * (Actually, I used CRC2 from PROBAS which is faster because it does a
- * table lookup for CRC. CRC2 called from my C program is lightning fast!)
- *
- * By the way, I've only been coding in C for about 8 days now so if you see
- * any gross inefficiency or my explanation isn't correct "to the letter"
- * please forgive me. But, I'm sure there are a lot of QB/C programmers out
- * there who will find this information useful regardless of any small
- * inaccuracies there may be in the explanation.
- *
- * Jim Kloss
- * Nochange Software - Home of "XChange" Unattended File Transfer
- * 540 Silver Pine Trail
- * Roswell, GA 30076-3323
- * (404)587-3815 voice
- * (404)641-8270 data
- ****************************************************************************/
-
- ---------------------------------------------------------------------------
- Subj: MIXED LANG PROG PART 9 Conf: (11) QBASIC
- ---------------------------------------------------------------------------
-
- #include <string.h>
- #include <stdio.h>
-
- /***************************************************************************
- * The format for the routine is CRC2(STRING$,HICRC%,LOCRC%) where we pass
- * it the STRING$ and it returns the HICRC% and LOCRC%. Note that we must
- * define the routine as 'fortran' (or 'pascal') to tell C that the
- * parameters are put onto the stack in the exact opposite order that it
- * normally puts them on. (No, there is not a 'basic' that I know of...)
- * The following statement is required to tell C about the QB function. It
- * is a prototype really and defines the kinds of variables you will be
- * sending and receiving.
- ****************************************************************************/
- extern void fortran crc2(struct dodo near *,int near *, int near *);
-
- /***************************************************************************
- * Everything must be declared NEAR which basic is going to work with since
- * it must work in the default data segment.
- ****************************************************************************/
- struct dodo {
- unsigned int sd_len;
- unsigned char near *sd_addr;
- } near str_des;
-
- /***************************************************************************
- * Main Program.
- ****************************************************************************/
- void main()
- {
-
- char temp[200];
- unsigned hicrc,locrc;
-
- strcpy(temp,"This is a test."); /* results should be 236 and 29 as hi/lo *
-
- str_des.sd_addr = temp;
- str_des.sd_len = strlen(temp);
-
- hicrc=locrc=0;
-
- printf("%u is the hicrc and %u is the locrc before call on %s\n",hicrc,locrc
- crc(&str_des,&hicrc,&locrc);
- printf("%u is the hicrc and %u is the locrc after call on %s\n",hicrc,locrc,
- printf("If everything worked right, the results should be 236 and 29!");
- }
-
- HOWIE
-