Calling Managed COBOL from un-managed code
The Microsoft .NET Framework and ‘managed’ code usage seem to be everywhere. More and more companies are adopting the use of managed frameworks to provide greater flexibility in their development environments and take advantage of the numerous features and benefits of the framework. But what if your shop isn’t on the road to .NET yet or fully? What if you have an existing COBOL environment that is not managed but in ‘native’ mode? How do you interact with managed code? How can you extend the use of your current application to reach out and utilize the features others have derived and published from the .NET Framework?
This article is an update of a previous article that was posted on the Micro Focus Community site in 2011 using NetExpress. This updated article will utilize the previous COBOL COM Server and client, but we will update the client from NetExpress to Visual COBOL. So let’s get started!
The technology we will be using to enable the call to the managed environment is part of the .NET Interop technology and is known as COM Callable Wrapper or “CCW”. Basically what happens is the .NET class you create is registered as a COM server so the native COBOL program can call it as such using the COM support available in Visual COBOL. One benefit of this approach is that once the COM module is registered within the environment any client can then call the server. Our example we are using COBOL but you could also create a “C” or VB client to call the server.
The demonstration consists of two parts, a managed Visual COBOL project called VCCOMServer and a native Net Express project called NXCOMClient. We are going to import the NetExpress project into Visual COBOL for Visual Studio so the developer will be working in one environment, Visual Studio. Please unzip the attached file VCCOMDemo.zip onto your hard drive, retaining the folder structure of the zip file. We’re going to start with the server program since it is already created and will require minimal effort to update.
When you unzip the supplied file you will have a directory called “VCCOMDemo” and it will contain two sub-directories, “NXCOMClient” and “VCCOMServer”
The VCCOMServer folder contains the managed code we will be using and defining as our COM server. Since the previous article was about using a managed environment we already have the managed code. If you select the VCCOMServer folder you will find a solution named “VCCOMServer.sln”, either double click on the solution file to open or from within Visual Studio navigate to the file and open it.
The VCCOMServer solution has a single program, VCCOMServer.cbl that implements an interface to the class. We are not going to spend time reviewing the class or interface as the intent is to demonstrate how to enable the code to be called as a COM Wrapper from within Visual Studio.
The secret is to tell Visual Studio when it builds the assembly, to register it as a COM assembly. This is conveniently done via a check box in the Project Properties. Double clicking on the ‘Properties’ entry and then selecting the ‘COBOL’ tab the following is presented
Click on the ‘Advanced…’ button to display the settings and you will see the following
In our example the checkbox for ‘Register for COM interop’ is already selected. By enabling this checkbox the build process will, once compilation is successful and completed, register the object as a COM service. Behind the scenes this is invoking “Regasm.exe” with the parameters of ‘tlb’ and ‘codebase’. The parameter ‘codebase’ creates a Codebase entry in the registry. The Codebase entry specifies the file path for an assembly that is not installed in the global assembly cache or GAC. ‘tlb’ generates a type library from the specified assembly containing definitions of the accessible types defined within the assembly. You can review the ‘Regasm’ utility at https://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.110).aspx for further information.
Once you have this setting enabled, save your work and rebuild the solution. The object will be registered as a ‘COM’ object and available in your environment. One note of caution, if you experience the following error when trying to register the object
You will need to close Visual Studio and reopen it with Administrator privileges. Executing the Regasm utility requires a higher level of authentication and this is achieved by running Visual Studio as an Administrator.
One additional note, when you are ready to promote your updates to production you will need to execute Regasm for the module via the command line. The Visual Studio implementation of Regasm is enabled for development and testing, you will need to execute Regasm to register your module for production use. In order to execute the Regasm utility you will need Administrator rights.
You should be building your COM server assemblies using the exact target type of your client application when registering it for use with COM. This is because an in-process COM Server DLL is loaded into the process space of the client program so they need to be the same “bitism”. You should therefore use a target CPU of either x86 or x64 in your Visual Studio project properties and not “anyCPU” when it needs to be registered for COM.
Prior to using these assemblies on a production computer they must first be registered on that computer using the Regasm tool. The file “Regasm.exe” comes with the .NET framework installation and can be found in the Microsoft.NET framework folder. There are different versions of regasm.exe available depending on the version of the .NET Framework you are targeting and whether the assembly is compiled for x86 or x64.
You execute “regasm.exe” from an Administrative command prompt by using the hardcoded path to the correct version as shown below:
(for explanation of options please see https://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.110).aspx)
.NET Framework 2.0, 3.0, or 3.5 for use with x86:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe myDLL.dll /codebase
.NET Framework 2.0, 3.0, or 3.5 for use with x64:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm myDLL.dll /codebase
.NET Framework 4.0 or higher for use with x86:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe myDLL.dll /codebase
.NET Framework 4.0 or higher for use with x64:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe myDLL.dll /codebase
Now that we have the server in place we can concentrate on the COBOL client that will be calling it. Our original solution was created using a previous version of the Micro Focus development environment called ‘NetExpress’. Visual COBOL is the current version of the NetExpress product reseated for the Visual Studio and Eclipse environments.
In order to utilize the Visual Studio environment we will need to upgrade the NetExpress project file to a Visual Studio solution. This is accomplished using the ‘Import NetExpress Project’ within Visual COBOL
By selecting ‘File’ then ‘New’ and finally ‘Import NetExpress Project’ a wizard will appear to walk you through the steps of importing and converting the NetExpress project to a Visual Studio Solution. Completing the steps will result in an updated project. We have left the original NetExpress project in the zip file in case you would like to test the import feature on your own.
The client program is a standard procedural based program utilizing what may be a few new features of the COBOL language for you.
The first item you see that you may not recognize is the ‘Class-Control’ header. The class-control header is an ISO2002 update to the language to enable the interaction with object-oriented classes and interface. In our example we are defining the server we would like to access, “VCCOMServer” as a class that is referenced by “$OLE$VCCOMServer.VCCOMServer”. If you’ll remember this was the name we assigned to our class-id in the server program.
The next item you may not have seen too often is the verb ‘invoke’. The ‘invoke’ verb is similar to the ‘call’ statement in procedural COBOL except it calls a method in an object oriented class. In our sample we are calling the methods “new”, “testVCstring”, “testVCint”, “testVCFloat” and “testVCGroup”.
There were no changes made to the client solution. We simply imported the NetExpress project, verified the properties and rebuilt the solution to generate the executable.
I placed a breakpoint at the first line of code in the Procedure Division and then began debugging the program.
If you’ll notice my ‘Autos’ window at the bottom, the object reference ‘anInstance’ is set to spaces because I haven’t executed a line of code as of this point. When I make the initial step and ‘instantiate’ the server I then have an address or pointer to a memory location where my copy of the server is
Instantiation is a formal way of saying I ‘made a copy of’ something. In this case I’ve made a copy of the VCCOMServer that I will be using and working with.
Stepping through the code we see the different variables come into view on the Autos window showing their values
Stepping through each of the method invocations we will see the following screen when complete
Calling managed COBOL from un-managed or native COBOL isn’t as scary or difficult as you may think. The secret is to make sure you register the managed code module for “COM interop”. In your existing procedural COBOL program you will need to add a ‘class-control’ header and then instantiate, or make a copy, of the module you wish to use. Then simply call the methods necessary using the ‘invoke’ verb. Using this technique you can also reference other managed code assemblies and provide new life to your procedural COBOL applications. Please remember when you are ready to promote your module to production to check with your IT Administrator about running the Regasm utility for your environment.
The ZIP file has all the necessary source code for you to follow along and see how to update the properties we’ve described in the article. Read through the code; learn from it and use it in your projects.
If you’d like to try out the samples and don’t have a copy of Micro Focus Visual COBOL, you can download the Personal Edition of Visual COBOL for free from the following link: http://www.microfocus.com/visualcobolpe