locked
COBOL Challenge in C# RRS feed

  • Question

  • I am trying to convert COBOL code to C#. One of the greatest challenges in general is revolves around the fact that COBOL is a loosely typed language as compared to C#.

    In COBOL you can define an I/O buffer to read and write to an external file as effectively a byte array (e.g. records being read and written may contain mixed data types - strings, integers, etc).

    A program may read a 100 byte record into this buffer and no type checking takes place.

    The program may then move this data to the equivalent of a C# structure with a single simple statement like:

        MOVE IO-BUFFER TO MY-STRUCTURE.

    What this effectively does in pick of the 100 byte IO-BUFFER and lay it into the structure from the beginning of the Structure without doing a member by member move. The reason this works in COBOL is that COBOL allocates and maintains fixed length areas in memory for each item in a structure and does not perform type checking when moving data into a variable. SO it effectively treats the structure as a byte array and simply moves one byte array to another. It is taken for granted that the data will always be in the correct format with fix length items that cause the move ot line up with the individual field types.

    Any idea how to do this in C# without having to write a special routine for each move to break the IO buffer up and do a field by field move into a structure?

    Thursday, April 26, 2007 11:44 PM

Answers

  • You could hijack the capabilities of the platform invoke marshaler to accomplish this.  I'll just show you the code without trying to explain it:

    using System;
    using System.IO;
    using System.Runtime.InteropServices;

    class Program {
      [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
      private struct CobolRecord {
        int intValue;
        double dblValue;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        string strValue;
      }

      static void Main(string[] args) {
        Type cobol = typeof(CobolRecord);
        int reclen = Marshal.SizeOf(cobol);
        byte[] recdata = new byte[reclen];
        IntPtr memdata = Marshal.AllocHGlobal(reclen);
        using (FileStream fs = new FileStream(@"c:\temp\test.bin", FileMode.Open, FileAccess.Read)) {
          fs.Read(recdata, 0, reclen);
          Marshal.Copy(recdata, 0, memdata, reclen);
          CobolRecord rec = (CobolRecord)Marshal.PtrToStructure(memdata, cobol);
        }
        Marshal.FreeHGlobal(memdata);
      }
    }

    Friday, April 27, 2007 5:11 PM
    Moderator

All replies

  • You could hijack the capabilities of the platform invoke marshaler to accomplish this.  I'll just show you the code without trying to explain it:

    using System;
    using System.IO;
    using System.Runtime.InteropServices;

    class Program {
      [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
      private struct CobolRecord {
        int intValue;
        double dblValue;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        string strValue;
      }

      static void Main(string[] args) {
        Type cobol = typeof(CobolRecord);
        int reclen = Marshal.SizeOf(cobol);
        byte[] recdata = new byte[reclen];
        IntPtr memdata = Marshal.AllocHGlobal(reclen);
        using (FileStream fs = new FileStream(@"c:\temp\test.bin", FileMode.Open, FileAccess.Read)) {
          fs.Read(recdata, 0, reclen);
          Marshal.Copy(recdata, 0, memdata, reclen);
          CobolRecord rec = (CobolRecord)Marshal.PtrToStructure(memdata, cobol);
        }
        Marshal.FreeHGlobal(memdata);
      }
    }

    Friday, April 27, 2007 5:11 PM
    Moderator
  • Hi. I'm interested in your project as I am about a third of the way through writing a COBOL compiler in C# which produces .NET executables and has the ability to use the .NET framework's class libraries.

    I opted for storing structures as either a struct or a few individual variables (depending on how it was declared in the COBOL source code). I'm still working on moving buffers into structures and vice versa. Are you trying to avoid doing this for speed reasons?

    So far, my compiler compiles the following programs correctly:
    99 Bottles of Beer
    Towers of Hanoi
    Hello World, using Console.WriteLine from .NET
    and a few NUnit tests (written in COBOL!) by referencing the nunit framework assembly.

    I keep a blog of my work on the project and downloads and examples here:

    http://www.sorn.net/projects/wildcat-cobol-compiler/


    Good luck with your project, and get in touch with me if you want to discuss any of the challenges. My email is sandy.dunlop@gmail.com
    Monday, May 7, 2007 8:42 PM
  • Hi Howard,

    have you finish the cobol / C# problem?

    have you an sample for me?

    I have nearly the same problem .Net / C# call cobol 32 Bite DLL
    The way down to the cobol program is working...
    I have an sample that workd with VB and WinForms and cobol
    Now I need WPF, c# and cobol


    Tuesday, June 23, 2009 2:51 PM