Created On:  05 July 2012

Problem:

A customer wishes to use a C# program to call an entry point in a native COBOL .dll.  How can a .NET Platform Invoke (P/Invoke) be used in C# to call a COBOL program and pass parameters back and forth?

Resolution:

There is a demo application attached here called cscallCOBOL.zip.

Unzip the demo to your C:\ drive retaining the folder structure in the zip file.

The solution file C:\cscallCOBOL\mycobol\cscallCOBOL.sln contains two projects.
The main project is a C# console application which calls the native COBOL project using Platform Invoke.

The program passes 3 parameters defined as a stringbuffer, an integer and a structure containing two string fields.
These fields are populated by C# and passed to COBOL.

COBOL then changes the values and returns to C# where they are displayed to the console.

The C# program looks like:

using

System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace

csmain
{
    class Program
    {
       [
StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct groupstruc
        {
           [
MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string companyname;
           [
MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
            public string contactname;
        } ;

       [
DllImport("mycobol.dll", EntryPoint = "mycobol", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
          static extern void mycobol(StringBuilder mystring, ref UInt32 myint, ref groupstruc mygroup);

       static void Main(string[] args)
       {
          StringBuilder mystring = new StringBuilder().Append("From C#").Append(' ', 13);
          UInt32 myint = 0;
          groupstruc mygroup;
          mygroup.companyname =
"Microsoft";
          mygroup.companyname = mygroup.companyname.PadRight(20,
' ');
          mygroup.contactname =
"Joe Smith";
          mygroup.contactname = mygroup.contactname.PadRight(20,
' ');
          mycobol(mystring,
ref myint, ref mygroup);
          System.
Console.WriteLine("String returned to C# = " + mystring);
          System.
Console.WriteLine("Int returned to C# = " + myint.ToString());
          System.
Console.WriteLine("Group company = " + mygroup.companyname);
          System.
Console.WriteLine("Group contact = " + mygroup.contactname);
       }
   }
}

The COBOL program looks as follows:

$set preservecase case
identification division.
program-id. mycobol.
data division.
working-storage section.
linkage section.
01 mystring pic x(20).
01 myint pic x(4) comp-5.
01 mygroup.
   05 mycompany pic x(20).
   05 mycontact pic x(20).
procedure division using mystring myint mygroup.
   move z"From COBOL" to mystring
   move 99 to myint
   move z"Chris Glazier" to mycontact
   move z"Micro Focus" to mycompany
   goback.