Microsoft KB Archive/64497

How to Use Named, Shared Memory Segments in OS/2 COBOL Program

PSS ID Number: Q64497 Article last modified on 11-21-1990

4.00 OS/2

Summary: Microsoft COBOL Professional Development System (PDS) version 4.00 can create protected mode programs that use named, shared memory segments. Named, shared memory segments are areas of memory used for interprocess communications (IPC). Their use involves calling three different OS/2 API functions. Below are two sample COBOL programs that demonstrate the use of named, shared memory segments. This information applies to Microsoft COBOL PDS version 4.00 for MS OS/2.

More Information: Named, shared memory segments can be used to communicate between processes. Their names have the following form: .ext The “.ext” extension is optional. The size of the segment can be up to 65,536 bytes. After the segment is allocated, it can be read from and written to using the COBOL subprograms X“85” and X“86”, which examine and set (respectively) a 1-byte address location. Typically, one process (called the “creator”) will allocate the segment and other programs (called “obtainers”) will obtain the address (selector) to it. The minimum OS/2 API functions that need to be called to use named, shared memory segments are the following:

For the Obtainers
For more information on calling OS/2 API functions from COBOL 4.00, see Chapter 14, “Interfacing With OS/2 API Routines,” in “Microsoft COBOL Professional Development System 4.0: Operating Guide” for version 4.00. For more information on named, shared memory segments and other IPC methods, see Chapter 13, “Interprocess Communication,” in “Advanced OS/2 Programming” by Ray Duncan (Microsoft Press, 1989). Following are two sample programs (CREATOR.CBL and OBTAINER.CBL) that demonstrate the use of named, shared memory segments. Run each program in a separate OS/2 screen group and switch between sessions to see the results. As you enter data from the creator session, it will appear in the obtainer screen group. Likewise, any data entered from the obtainer session will appear in the creator screen group. To compile and link the programs, enter the following commands at the OS/2 command prompt (note that these command lines assume you are not using a COBOL.DIR file): cobol creator; link creator,,,coblib os2; cobol obtainer; link obtainer,,,coblib os2;

CREATOR.CBL
* CREATOR.CBL allocates a shared memory segment with a size of 2 * bytes and initializes both of those bytes to 0. It then sits * in a loop that reads the first byte of the segment and also * polls the keyboard. Any input from the keyboard is written * to the second byte of the shared memory segment (to be read by * OBTAINER.CBL). Whenever the first byte of the segment is a * character other than null (written there by OBTAINER.CBL), it  * is displayed on the screen. The program terminates when it * reads an ESC character either from the keyboard or the * first byte of the shared memory segment. IDENTIFICATION DIVISION. PROGRAM-ID. Creator. * COBOL will use OS/2 API calling convention, not its default. SPECIAL-NAMES. CALL-CONVENTION 3 IS OS2API. DATA DIVISION. WORKING-STORAGE SECTION. *  DosAllocShrSeg parameters. *  Global name of the shared segment (null-terminated). 01 SegmentName  PIC  X(12)       VALUE &quot;\SHAREMEM\A&quot; & X&quot;00&quot;. *  Receives the segment address. 01 Selector     PIC  9(4) COMP-5. *  Other variables. *  Receives error returned from DosAllocShrSeg. 01 ErrorCode    PIC S9(4) COMP-5. *  Receives data read from byte 0 of the shared memory segment *  and also receives keyboard input. 01 Buffer       PIC  X.  *   Used in calls to X&quot;86&quot; and X&quot;85&quot; to write and read data to  *   and from the shared memory segment. 01 SegmentAdd   PIC  9(5). 01 OffsetAdd    PIC  9(5)       VALUE 0. PROCEDURE DIVISION. *   Allocate the shared memory segment (size is 2 bytes). CALL OS2API &quot;__DosAllocShrSeg&quot; USING BY VALUE    2 SIZE 2, BY REFERENCE SegmentName, BY REFERENCE Selector RETURNING   ErrorCode. *   Check if an error occurred. IF ErrorCode NOT = 0 THEN DISPLAY &quot;ERROR &quot; ErrorCode &quot; allocating segment&quot; CALL X&quot;E5&quot; STOP RUN ELSE DISPLAY &quot;The memory segment has been allocated&quot; MOVE Selector TO SegmentAdd END-IF. *   Initialize the receive buffers of both the creator (byte 0  *    of the shared memory segment) and the other process (byte  *    1 of the shared memory segment) CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, X&quot;00&quot;. MOVE 1 TO OffsetAdd. CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, X&quot;00&quot;. *   Loop until an ESC character is read from the keyboard. PERFORM UNTIL Buffer = X&quot;1B&quot; *      If a key is waiting to be read from the keyboard, write *      it to the receive buffer of the other process. CALL X&quot;D9&quot; USING Buffer IF Buffer NOT = X&quot;00&quot; THEN CALL X&quot;83&quot; USING Buffer MOVE 1 TO OffsetAdd CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, Buffer END-IF *      If the user did not enter an ESC character, check if  *       a new byte has been written to the receive buffer by the *      other process. If so, read and display the byte and *      replace it with a null. IF Buffer NOT = X&quot;1B&quot; THEN MOVE 0 TO OffsetAdd CALL X&quot;85&quot; USING SegmentAdd, OffsetAdd, Buffer CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, X&quot;00&quot; EVALUATE Buffer WHEN X&quot;0D&quot; DISPLAY &quot; &quot; WHEN X&quot;01&quot; THROUGH X&quot;FF&quot; DISPLAY Buffer WITH NO ADVANCING END-EVALUATE END-IF END-PERFORM. *   Release selector for the shared memory segment and end. CALL OS2API &quot;__DosFreeSeg&quot; USING BY VALUE Selector. STOP RUN.

OBTAINER.CBL
* OBTAINER.CBL gets the address of the shared memory segment * allocated by CREATOR.CBL. It then sits in a loop that reads * the second byte of the segment and also polls the keyboard. * Any input from the keyboard is written to the first byte of * the shared memory segment (to be read by CREATOR.CBL). * Whenever the second byte of the segment is a character other * than null (written there by CREATOR.CBL), it is displayed on * the screen. The program terminates when it reads an ESC * character either from the keyboard or the second byte of the * shared memory segment. IDENTIFICATION DIVISION. PROGRAM-ID. Obtainer. * COBOL will use OS/2 API calling convention, not its default. SPECIAL-NAMES. CALL-CONVENTION 3 IS OS2API. DATA DIVISION. WORKING-STORAGE SECTION. *  DosGetShrSeg parameters. *  Global name of the shared segment (null-terminated). 01 SegmentName  PIC  X(12)       VALUE &quot;\SHAREMEM\A&quot; & X&quot;00&quot;. *  Receives the segment address. 01 Selector     PIC  9(4) COMP-5. *  Other variables. *  Receives error returned from DosGetShrSeg. 01 ErrorCode    PIC S9(4) COMP-5. *  Receives data read from byte 1 of the shared memory segment *  and also receives keyboard input. 01 Buffer       PIC  X.  *   Used in calls to X&quot;86&quot; and X&quot;85&quot; to write and read data to  *   and from the shared memory segment. 01 SegmentAdd   PIC  9(5). 01 OffsetAdd    PIC  9(5). PROCEDURE DIVISION. *   Get the address of the shared memory segment. CALL OS2API &quot;__DosGetShrSeg&quot; USING BY REFERENCE SegmentName, BY REFERENCE Selector RETURNING   ErrorCode. *   Check if an error occurred. IF ErrorCode NOT = 0 THEN DISPLAY &quot;ERROR &quot; ErrorCode &quot; getting segment&quot; CALL X&quot;E5&quot; STOP RUN ELSE DISPLAY &quot;The memory segment has been gotten&quot; MOVE Selector TO SegmentAdd END-IF. *   Loop until an ESC character is read from the keyboard. PERFORM UNTIL Buffer = X&quot;1B&quot; *      If a key is waiting to be read from the keyboard, write *      it to the receive buffer of the creator process. CALL X&quot;D9&quot; USING Buffer IF Buffer NOT = X&quot;00&quot; THEN CALL X&quot;83&quot; USING Buffer MOVE 0 TO OffsetAdd CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, Buffer END-IF *      If the user did not enter an ESC character, check if  *       a new byte has been written to the receive buffer by the *      creator process. If so, read and display the byte and *      replace it with a null. IF Buffer NOT = X&quot;1B&quot; THEN MOVE 1 TO OffsetAdd CALL X&quot;85&quot; USING SegmentAdd, OffsetAdd, Buffer CALL X&quot;86&quot; USING SegmentAdd, OffsetAdd, X&quot;00&quot; EVALUATE Buffer WHEN X&quot;0D&quot; DISPLAY &quot; &quot; WHEN X&quot;01&quot; THROUGH X&quot;FF&quot; DISPLAY Buffer WITH NO ADVANCING END-EVALUATE END-IF END-PERFORM. *   Release selector for the shared memory segment and end. CALL OS2API &quot;__DosFreeSeg&quot; USING BY VALUE Selector. STOP RUN. Copyright Microsoft Corporation 1990.