Basic PDS 7.10 Call to C Routine to Open > 15 Files Fails (71795)
This article was previously published under Q71795
SYMPTOMS
Calling a Microsoft C 6.00 routine from a Microsoft Basic Professional
Development System (PDS) version 7.10 program and trying to open more
than 15 files in the C routine will fail. The C routine cannot open
more than 15 files even if the C run-time library has been modified to
support more than 15 files, and the Basic program calls interrupt 21
Hex, with function 67 Hex, to obtain more file handles.
STATUS
Microsoft has confirmed this to be a bug in Microsoft Basic Professional
Development System (PDS) version 7.10 and Microsoft C PDS version 6.00. We
are researching the problem and will post new information here in the
Microsoft Knowledge Base as it becomes available.
MORE INFORMATION
The failure occurs because the C file-open routines check the run-time
variable _nfile to see if there are enough file handles available to
open the file.
You can modify the C 6.00 run time to support more than 15 files, as
described in the C 6.00 documentation; however, if you link a C 6.00
routine with Microsoft Basic PDS 7.10, the modified portion of the run
time will not get incorporated into the actual executable program (the
Basic run-time code is used instead).
Increasing the file handle count by calling interrupt 21 Hex with
function 67 Hex in Basic does not resolve the problem because this
method does not change the run-time variable that C 6.00 is checking
(_nfile) to indicate the new number of available file handles.
The following method to work around the problem directly modifies the
run-time variable _nfile from the C 6.00 function that is called
from Basic PDS 7.10. This workaround is based on internal details of
the C and Basic run-time routines, and is not guaranteed to work for
versions other than those specified above. If you chose to use this
workaround, be certain that the call to interrupt 21 Hex with function
67 Hex (to increase the available file handles) has been done and
returned successfully before calling the C function that modifies
_nfile.
Compile and link the workaround programs as follows:
BC /o test ;
CL /c /AM files.c ;
LINK test files,,,BCL71ENR MLIBCE QBX /NOE /NOD ;
TEST.BAS
'$INCLUDE: 'QBX.BI'
DECLARE SUB profile CDECL ()
DIM InRegs AS RegType, OutRegs AS RegType
CLS
InRegs.ax = &H6700
InRegs.bx = 40
CALL Interrupt(&H21, InRegs, OutRegs) 'Increases MS-DOS file handles.
CALL profile ' Calls the C routine.
PRINT "In Basic again."
END
FILES.C
#define SYSCALL 0x21
#include <stdio.h>
#include <conio.h>
#include <io.h>
#include <dos.h>
#include <bios.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <sys\locking.h>
#include <share.h>
#include <stdlib.h>
union REGS regs;
extern int _nfile; /* run-time variable */
void extern profile(void);
void extern profile(void)
{
int i,handle[20];
char filename[20][20];
_nfile = 40;
strcpy(filename[0],"t1.tmp\0"); strcpy(filename[1],"t2.tmp\0");
strcpy(filename[2],"t3.tmp\0"); strcpy(filename[3],"t4.tmp\0");
strcpy(filename[4],"t5.tmp\0"); strcpy(filename[5],"t6.tmp\0");
strcpy(filename[6],"t7.tmp\0"); strcpy(filename[7],"t8.tmp\0");
strcpy(filename[8],"t9.tmp\0"); strcpy(filename[9],"t10.tmp\0");
strcpy(filename[10],"t11.tmp\0"); strcpy(filename[11],"t12.tmp\0");
strcpy(filename[12],"t13.tmp\0"); strcpy(filename[13],"t14.tmp\0");
strcpy(filename[14],"t15.tmp\0"); strcpy(filename[15],"t16.tmp\0");
strcpy(filename[16],"t17.tmp\0"); strcpy(filename[17],"t18.tmp\0");
strcpy(filename[18],"t19.tmp\0"); strcpy(filename[19],"t20.tmp\0");
for (i=0;i<20;i++)
{
handle[i] = sopen(filename[i], O_BINARY | O_RDWR | O_CREAT,
SH_DENYNO, S_IREAD | S_IWRITE);
if( handle[i] == -1 )
printf( "Can't open file %d\n",i );
else
printf( "Opened file %d!\n",i);
}
printf("end of C, going back to Basic \n");
}
Modification Type: |
Minor |
Last Reviewed: |
1/9/2003 |
Keywords: |
KB71795 |
|