Created On:  27 July 2012

Problem:

I have a managed code COBOL project in Visual COBOL for Visual Studio that contains multiple COBOL programs that I need to call from a C# main program. I am using the ilsmartlinkage compiler directive so that the COBOL compiler will generate a .NET class for the linkage section group items that are being used as parameters to the COBOL programs.

Each COBOL program has the same linkage section parameters defined by using a common copybook.

This works fine if there is only one program in the COBOL project but as soon as I add a second program, I get compile errors because it is trying to generate a duplicate class name for the linkage section group.

How do I get around this?

Resolution:

You can get around this by using the ilsmartnest directive in conjunction with ilsmartlinkage.

When specifying the ilsmartnest directive the compiler will generate a unique class for each of the parameter groups by qualifying its name with the program name that it is in.

An example is attached.

Subroutine Program1.

*------------------------------------------------------------------------------*
*                                 PROGRAM1                                     *
*                                                                              *
* This COBOL program is being compiled with the ilsmartlinkage and ilsmartnest *
* compiler directives which are being set in the project properties for the    *
* testsmartlink project. This project also contains PROGRAM2.cbl which also    *
* uses the same linkage section items specified in copybook testcopy.cpy.      *
*                                                                              *
* Because both programs use the same group item name as a parameter in linkage *
* this will cause a compiler error if only the ilsmartlinkage directive is used*
* as it will try to generate the same class for the group item in both programs*
*                                                                              *
* In order to get around this the ilsmartnest directive can be used with the   *
* ilsmartlinkage directive which causes each group item to be generated as a   *
* different class using the program name as a qualifying namespace.            *
*------------------------------------------------------------------------------*

program-id. Program1 as "testsmartlink.Program1".
data division.
working-storage section.
linkage section.
copy testcopy.cpy.
procedure division using clientrecord.
   move "54321" to clientid
   move "Chris" to clientname
   goback.
end program Program1.

subprogram Program2:

program-id
. Program2 as "testsmartlink.Program2".
data division.
working-storage section.
linkage section.
copy testcopy.cpy.
procedure division using clientrecord.
   move "99999" to clientid
   move "John" to clientname
   goback.
end program Program2.

copybook testcopy.cpy:

01
ClientRecord.
   05 ClientId pic x(10).
   05 clientname pic x(20).

C# main program Program:
// This example program demonstrates the use of the ilsmartlinkage and ilsmartnest directives in COBOL.
// This main C# program will call both Program1 and Program2 COBOL programs while passing a class as a parameter.
// The parameter class is generated automatically by the COBOL compiler because the ilsmartlinkage directive is
// on in the COBOL project. Because we are calling two COBOL programs that have the same linkage section defined,
// using the same parameter name, the ilsmatnext directive must also be set. This causes the compiler to generate
// each parameter class separately qualifying it with the program name.
//-----------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using testsmartlink;

namespace
ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
         //Create new instance of COBOL Program1.
           Program1 myprogram = new Program1();
         //Create new instance of Clientrecord class qualifying with Program1 name.
           Program1.Clientrecord cr = new Program1.Clientrecord();
           cr.Clientid =
"1234";
           cr.Clientname =
"Fred";
           myprogram.Program1(cr);
           Console.Out.WriteLine("ID: " + cr.Clientid + " Name: " + cr.Clientname);
         //Create new instance of COBOL Program2.
           Program2 myprogram2 = new Program2();
         //Create new instance of Clientrecord class qualifying with Program2 name.
           Program2.Clientrecord cr2 = new Program2.Clientrecord();
           cr2.Clientid =
"9876";
           cr2.Clientname =
"Joe";
           myprogram2.Program2(cr2);
           Console.Out.WriteLine("ID: " + cr2.Clientid + " Name: " + cr2.Clientname);
        }
    }
}