Microsoft KB Archive/40644

How to Put Multiple COBOL Modules in Dynamic Link Library

PSS ID Number: Q40644 Article last modified on 06-29-1990

3.00 3.00a OS/2

Summary: With Microsoft COBOL versions 3.00 and 3.00a, you may often want to include several subprograms in one dynamic link library (DLL) for use in OS/2 protected mode. You can do this by adding each subprogram name in the EXPORTS list that is used during LINK time. The first routine in the DLL must have the same name as the DLL itself, and this routine must be CALLed before any other subprogram in the DLL can be CALLed. Failure to do this will result in run-time error 173, “Failed to find program: .” The DEF file named REGISTER.DEF below is used to create the REGISTER.DLL that contains the subprograms CALLED1 and CALLED2.

More Information: A specific format must be used to both create and CALL the COBOL DLL. First, the very first routine in the DLL must have the same name as the DLL itself. In the program example below, REGISTER.COB is the first routine that is linked into REGISTER.DLL. Second, before the rest of the routines can be CALLed from a COBOL program, the first routine, which has the same name as the .DLL itself, must be CALLed. So in the program example below, REGISTER.COB is first CALLed, which causes REGISTER.DLL to be loaded. After this step, the other COBOL subprograms, CALLED1 and CALLED2, can be CALLed at any time and in any order. Since the purpose of the first routine in the DLL (the one that has the same name as the DLL itself) is only to load the rest of the routines in the DLL, we recommend that this routine be a “do nothing” routine that is only CALLed and immediately returns. Failure to follow the two requirements above will result in run-time error 173 “Failed to find program .” You can also receive this error if the DLL is not along the LIBPATH environment variable that is SET in your OS/2 CONFIG.SYS file. Note: This method of constructing and CALLing multiple routines in DLLs is required only in COBOL 3.00 and 3.00a. In other languages that support DLLs, such as Microsoft C, subprograms can be called in any order and the first routine in the DLL is not required to have the same name as the DLL itself. Note: You cannot CALL a COBOL .DLL from other languages, such as C. Also, you cannot access a COBOL .DLL from inside Microsoft Excel (which can access .DLLs in macros). This limitation occurs because there are two ways to load .DLLs: Microsoft languages and applications (such as C, FORTRAN, and Excel) use one method, and COBOL uses the other. Both methods are legitimate, but not exactly compatible. Micro Focus implemented one version of loading .DLLs before Microsoft established the other unwritten standard in its applications and languages. Therefore, you cannot call COBOL .DLLs from any language or application except COBOL.

Program Example Creation
To create the program using the code below, follow these steps: 1. Compile all four of the following programs: PCOBOL caller.cob; PCOBOL register.cob; PCOBOL called1.cob; PCOBOL called2.cob; 2. Link the main program as follows: LINK caller /nop /nod,,,pcobol.lib+doscalls.lib; 3. LINK the other routines to create a DLL as follows: LINK register+called1+called2 /nop/nod,,,pcobol+doscalls,register.def

Program Files Needed
The following are the files you need to create the program: 1. The following is REGISTER.DEF: LIBRARY INITINSTANCE ; States that this is a DLL PROTMODE ; Needs to run in protected mode DATA NONSHARED ; Expects OS/2 to duplicate data areas for each task CODE LOADONCALL ; Load when needed ; ‘Register’ is the first routine called and has the same ; name as the DLL itself. This loads the rest of the routines ; so that they can be CALLed from COBOL. The rest are as follows: EXPORTS register @1 ; First routine in the DLL is Register EXPORTS called1 @2 ; Second routine in the DLL is CALLED1 EXPORTS called2 @3 ; Second routine in the DLL is CALLED2 2. The following is CALLER.COB: $SET ANS85 * CALLER.COB DATA DIVISION. WORKING-STORAGE SECTION. 77 USER-CHOICE PIC 9 VALUE 0. PROCEDURE DIVISION. * THIS IS THE INITIALIZATION ROUTINE WHICH PULLS * IN ALL OF THE REST OF THE ROUTINES IN THE DLL. * IT SHOULD BE A ‘DO NOTHING’ ROUTINE WHICH HAS THE * SAME NAME AS THE DLL ITSELF. CALL “REGISTER”. PERFORM UNTIL USER-CHOICE = 3 DISPLAY “CHOOSE THE ORDER YOU WANT THE SUBPROGRAMS TO” AT 1910 DISPLAY “BE EXECUTED IN:” AT 2010 DISPLAY “1) CALLED1 FOLLOWED BY CALLED2” AT 2110 DISPLAY “2) CALLED2 FOLLOWED BY CALLED1” AT 2210 DISPLAY “3) QUIT” AT 2310 DISPLAY “ENTER CHOICE (1 OR 2):” AT 2410 ACCEPT USER-CHOICE * ** CLEAN UP THE SCREEN. DISPLAY &quot; &quot; AT 2510 DISPLAY &quot; &quot; WITH BLANK SCREEN DISPLAY “IN MAIN” EVALUATE USER-CHOICE WHEN 1 CALL “CALLED1” DISPLAY “IN MAIN AFTER EXECUTING CALLED1” CALL “CALLED2” DISPLAY “BACK TO MAIN AFTER EXECUTING CALLED2” WHEN 2 CALL “CALLED2” DISPLAY “IN MAIN AFTER EXECUTING CALLED2” CALL “CALLED1” DISPLAY “BACK TO MAIN AFTER EXECUTING CALLED1” WHEN 3 DISPLAY &quot; &quot; WITH HIGHLIGHT AT 2510 WHEN OTHER DISPLAY “THAT IS NOT ONE OF THE CHOICES!” WITH HIGHLIGHT AT 2510 END-EVALUATE END-PERFORM. STOP RUN. 3. The following is REGISTER.COB: $SET ANS85 IDENTIFICATION DIVISION. PROGRAM-ID. REGISTER. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. * THIS IS A ‘DO NOTHING’ SUBPROGRAM WHICH IS CALLED * ONLY TO CAUSE THE OTHERS IN THE DLL TO BE LOADED. * IT MUST HAVE THE SAME NAME AS THE DLL ITSELF. EXIT PROGRAM. 4. The following is CALLED1.COB: $SET ANS85 IDENTIFICATION DIVISION. PROGRAM-ID. CALLED1. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. DISPLAY “IN THE CALLED1 PROGRAM”. DISPLAY “ABOUT TO RETURN TO THE MAIN PROGRAM”. EXIT PROGRAM. 5. The following is CALLED2.COB: $SET ANS85 IDENTIFICATION DIVISION. PROGRAM-ID. CALLED2. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. DISPLAY “IN THE CALLED2 PROGRAM”. DISPLAY “ABOUT TO RETURN TO THE MAIN PROGRAM”. EXIT PROGRAM.

Copyright Microsoft Corporation 1990.