COBOL Calling C#


Description 

Last month we published an article detailing how to call COBOL modules from C#. One of our readers, Fakher Halim from the Chicago area, downloaded the project files, read through the code and had it working in no time. As he stated he had "low expectations, but suddenly found it to be capable of doing just about anything". He found the interactions with the .NET libraries quite easy to use and had a specific requirement to reverse what was done in the article; that is to call .NET assemblies (C #or VB.NET) from procedural COBOL. I forwarded him a sample of the code I was working on for this month's article and he adapted it to his requirements and sent it back to me.

So, in this article we'll take a look at how a procedural COBOL program can be updated with a few statements to enable a call to a C# module. The changes are actually quite minor and demonstrate one method to access other .NET modules. We will use a simple Console application to represent our procedural COBOL. Again, with sincere thanks to Fakher!

Accessing .NET Assemblies

As Fakher demonstrated, existing procedural COBOL code can be updated with a few statements to enable it to access .NET assemblies and data types. This is but one method to achieve accessing .NET assemblies. Another method is to leave the existing procedural COBOL code as is and create an interface program. The interface program would be an object oriented COBOL program (CLASS-IS instead of PROGRAM-ID) that would utilize the .NET data types and perform the marshalling between the standard COBOL PIC clauses and the .NET data types. While the Micro Focus compiler does do this behind the scenes for you the interface method allows you to keep your procedural code in its original context while still taking advantage of the .NET Framework.

 Program Updates

In order to access the .NET assemblies there are a couple of updates that have to be done. The updates are the addition of a repository section, adding some new variables defined using the.NET data types instead of the standard COBOL PIC clauses, and enabling access to the .NET namespace. Let's take a look at these in a bit more detail.

The repository section or paragraph is an ISO2002 extension that allows for the definition of program prototype, function prototype, class, delegate, enum, interfaces and property names. It also allows for the declaration of functions without having to use the word 'FUNCITON'. Our repository section is defined as

repository.JPG

The assembly we're going to access is named 'CSUPATE' and the class within the assembly is named 'Class1'. The variable 'cslib' is defined by the user and can be anything that makes sense to the user.

Our next update is in the Working-Storage Section. The update done here was to include the definition of some new variables defined using the .NET data type definitions.

WorkStorage.JPG

In Micro Focus COBOL we can access the data type definitions directly without having to include any updates in the Repository Section. One item to note is the definition of 'csupdate'. This is an object reference. An object reference is an ISO2002 extension. It defines a reference to an object, in our case the CSUPDATE.Class1 object, that we are attempting to access or use in our program. What we are setting up is a storage location for the object we are going to use. In OO terms this is called 'instantiation'. More on that in a bit.

Now we're ready to make some changes to the Procedure Division. Our first change is about establishing access to the object CSUPDATE.Class1.  We do that with the following code:

Instantiate.JPG

This is called 'instantiating an object', or simply 'instantiation'. Instantiation is the technique used to create addressability to an object so that it can be used by the current or calling program. In .NET we use the 'new' method to create the copy of the CSUPDATE namespace and store it's location in the 'csupdate' variable.

After we've established addressability to the namespace we next need to call it or invoke it in OO terms. That is done by the following line of code:

invoke.JPG

In this statement we are doing two things at the same time, calling the method 'CBL' and setting a return value, 'retval' in this case, to the return code set in the called method. When we call the method 'CBL' we are passing it two variables as required by it's definition. The variable 'dbl' is a float-long and 'msg' is defined as a type text as we defined in the Working-Storage Section. Notice also these are being passed by reference using the 'REFERENCE' key word. This saves on storage by passing the reference to the location of the variable, rather than making a copy of the variable and passing it along. The main reason to pass variables by REFERENCE is to have the potential of getting them modified by the C# program.

Finally we need to update the original variables in the procedural COBOL code after we return from the called assembly. This is done so we can use the resulting values in the original COBOL code without having to look through the whole program and updating all the variable references with the new names of 'dbl' and 'msg'. This is done with the following code:

SetVars.JPG

By using this method we limit the changes to the source code and thus reduce the risk of changing the code as well as hopefully saving some time in testing.

Wrap-Up

As we have seen the changes to the original procedural COBOL code were relatively minor. To recap the changes were:

  1. The addition of the Repository Section and a reference to the namespace and class we are going to be accessing
  2. Adding a couple of variables in the Working-Storage Section defined using native .NET data types
  3. Instantiating the namespace we're going to access
  4. Accessing the method in the namespace that will provide us with the information we are looking for and finally
  5. Moving the variables returned from the namespace to the original variables in the COBOL program

Download the sample, give it a try. If you don't have a copy of NetExpress for .NET you can obtain a free copy at http://www.microfocus.com/Resources/Communities/Academic/shop/index.asp

Again, my sincere Thanks to Fakher Halim for his sample.

Happy Coding!