Microsoft KB Archive/112769

= PRB: How to Break Program into Modules When Can't Create .EXE =

Article ID: 112769

Article Last Modified on 8/16/2005

-

APPLIES TO


 * Microsoft BASIC Professional Development System 7.0
 * Microsoft BASIC Professional Development System 7.1
 * Microsoft QuickBasic 4.0
 * Microsoft QuickBASIC 4.0b
 * Microsoft QuickBasic 4.5 for MS-DOS
 * Microsoft Visual Basic for MS-DOS

-



This article was previously published under Q112769



SYMPTOMS
It is not always possible to create an EXE file from a program that runs in the development environment of the products listed above. The development environment and the compiler itself, have different limitations on amount of code and data they can handle.



RESOLUTION
Break the Basic program into modules. The More Information section in this article shows you how.



MORE INFORMATION
The Basic compiler and linker can only create executable files in 64K segments. If a segment grows larger than 64K, one of several error messages will be displayed indicating that the program is too large or has run out of memory.

To solve the problem, you need to create multiple files, each of which creates less than 64K of executable code; Then link them together. This translates into an approximate size limitation of not over 55K of source code per file with a recommended maximum of about 45K to allow room for growth.

The development environments for Microsoft's Basic languages incorporate features that greatly simplify the process of creating new files and moving SUB and FUNCTION procedures to them.

The goal of the modularization process is to move part of the program to one or more other files. This can only be done with SUB and FUNCTION procedures. If your program makes extensive or exclusive use of the GOSUB and DEF FN commands, it will probably be necessary to convert a portion of them to SUB and FUNCTION procedures, respectively.

The main difference between SUB procedures and GOSUB commands within a single module is that a SUB procedure can't use variables from the main module unless the variables are made global or are passed to the SUB procedure as parameters. The advantage of a subroutine is that it can be called from another module, allowing you to create multiple modules that simply contain other SUB and FUNCTION procedures.

CAUTION: Test your program after each conversion to make certain everything is still working correctly.

Step-by-Step Example

 * 1) First and foremost, open your program in the development environment and choose Save As from the File menu to save your file in TEXT format. Changing the name of the file is not necessary. Exit the development environment and make a backup so that you can start over if a problem occurs.
 * 2) Move as much code as possible to SUB and FUNCTION procedures to allow the movement of code to other modules.
 * 3) Create an Include module once a sufficient number of SUB procedures have been created to allow all modules to meet sizing constraints. The include file is used to save having to repeat all the declarations, COMMON blocks, and TYPE statements in each module where they are used. Move all DEFINE, TYPE, and DIM SHARED statements into the Include module. Then add the include statement to the module level code of all your modules:

REM $INCLUDE: 'filename'
 * 1) Convert all DIM SHARED statements in the include file to COMMON SHARED. COMMON SHARED variables are like the parameters of a SUB or FUNCTION procedure. They must always be used in the same order or errors will occur. Using an Include file for all COMMON SHARED variables prevents running into problems with incorrect ordering. Arrays can't be dimensioned in a COMMON SHARED statement, so you must place a DIM statement in the main program to specify the array size. Specify the COMMON SHARED statement for an array in this manner:

COMMON SHARED A AS INTEGER
 * 1) Test your program to ensure everything is still working correctly by running it in the environment.
 * 2) In the development environment, open your program and choose Create (New Module in Visual Basic for MS-DOS) from the File menu to create a module. Do not use the same file name with a different extension that you used for your program (such as MAIN.BAS and MAIN.1). This will cause errors when creating an EXE file.
 * 3) Add the same include statement(s) you used in your main file to the top of the module file you created in step 6.
 * 4) Press the F2 key, and use the Move option to transfer the SUB and FUNCTION procedures from your main file to the file you created in step 6. When you finish, choose Save All from the File menu to save your changes. This also creates a .MAK file that will load both your files when the main file is opened.
 * 5) Test your program to ensure everything is still working correctly by running it in the environment.
 * 6) From the Run menu, choose Make .EXE to create an executable program. Microsoft recommends using the DEBUG compiler option (/D), which inserts runtime error checking of array indices and can help avoid other potential problems. You should end up with a working executable program.

Code to Use to Test Step-by-Step Example
You can use the following code to test the Step-by-Step example given above. '======================================================= 'File OLDMAIN.BAS DEFINT A-Z

DIM A(1 TO 100) AS INTEGER

FILE$="MYFILE.TXT" GOSUB READFILE CALL SORTFILE               ' No example given or needed FILE$="MYFILE.SRT" GOSUB WRITEFILE END READFILE: OPEN FILE$ FOR INPUT AS #1 INPUT NLINES FOR I=1 TO NLINES INPUT #1,A(I) NEXT I    CLOSE #1 RETURN WRITEFILE: OPEN FILE$ FOR OUTPUT AS #2 PRINT NLINES FOR I=1 TO NLINES PRINT #2,A(I) NEXT I    CLOSE #2 RETURN

'======================================================= 'The following files were created from OLDMAIN.BAS

'File NEWMAIN.BI DECLARE SUB READFILE(FILE$) DECLARE SUB WRITEFILE(FILE$) DECLARE SUB SORTFILE COMMON SHARED A AS INTEGER COMMON SHARED NLINES AS INTEGER

'======================================================= 'File NEWMAIN.BAS REM $INCLUDE: NEWMAIN.BI'

DIM A(1 TO 100) CALL READFILE("MYFILE.TXT") CALL SORTFILE               ' No example given or needed CALL WRITEFILE)"MYFILE.SRT") END

'======================================================= 'File NEWSUBS.BAS REM $INCLUDE: NEWMAIN.BI' SUB READFILE(FILE$) DIM I AS INTEGER OPEN FILE$ FOR INPUT AS #1 INPUT NLINES FOR I=1 TO NLINES INPUT #1,A(I) NEXT I    CLOSE #1 END SUB

SUB WRITEFILE(FILE$) DIM I AS INTEGER OPEN FILE$ FOR OUTPUT AS #2 PRINT NLINES FOR I=1 TO NLINES PRINT #2,A(I) NEXT I    CLOSE #2 END SUB

