Skip to main content

[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

This can be done in Visual COBOL R4 using the SmartLinkage directive.

Open up the Samples Browser under Start Menu->All Programs->Visual COBOL 2010->Visual COBOL Samples and then select the sample COBOL Book in the left column and C# WinBook in the right column and open this in Visual Studio 2010.

Look at the properties on the LegacyBook project under the COBOL tab.
The following Directives are set:

ilsmartlinkage ilcutprefix(lnk-b-) ilcutprefix(lnk-)

This tells the COBOL compiler to make the COBOL group items in the linkage section available to C# as individual elementary items with a .NET type so that C# can access the individual fields directly.

Please see the documentation for this here:


[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

This can be done in Visual COBOL R4 using the SmartLinkage directive.

Open up the Samples Browser under Start Menu->All Programs->Visual COBOL 2010->Visual COBOL Samples and then select the sample COBOL Book in the left column and C# WinBook in the right column and open this in Visual Studio 2010.

Look at the properties on the LegacyBook project under the COBOL tab.
The following Directives are set:

ilsmartlinkage ilcutprefix(lnk-b-) ilcutprefix(lnk-)

This tells the COBOL compiler to make the COBOL group items in the linkage section available to C# as individual elementary items with a .NET type so that C# can access the individual fields directly.

Please see the documentation for this here:


[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

I see.

I do not wan't to assign every single field in the structure.
What I wan't is to assign the level 1 item only as the parameter.

Is there a way to do that or can i wrap a C# byte[] or sbyte[] into a MF Reference?

(In Java with the RuntimeSystem I can put a simple byte[] as parameter.)


[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

Are you referring to calling a native COBOL .dll from C# or a managed COBOL .dll?
Because you reference that you can do this in Java I will assume that it is referring to C# calling native COBOL.

You can do this using a Platform/Invoke call from C# and passing the group item as a StringBuffer or using a C structure etc.

The following is a simple example of C# calling a function named TESTCALL in a native COBOL .dll named cspinvoke.dll and having COBOL populate the group and return to C# where the fields are displayed.


    {
            StringBuilder sb = new StringBuilder(44);
            NativeCobol.TESTCALL(sb);
            txtName.Text = sb.ToString().Substring(0, 20);
            txtCompany.Text = sb.ToString().Substring(20, 20);
            txtAmount.Text =  sb.ToString().Substring(40, 4);
        }
    }
    public class NativeCobol
    {
        [DllImport("cspinvoke.dll", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
        public static extern void TESTCALL(StringBuilder cobparams);
    }


and the called COBOL:


       identification division.
       program-id. TESTCALL.
       data division.
       working-storage section.
       linkage section.
       01 group-item.
          05 g-name    pic x(20).
          05 g-company pic x(20).
          05 g-amount  pic 9(4).
       procedure division using group-item.

           move "C. Glazier" to g-name
           move "Micro Focus" to g-company
           move 1234 to g-amount
           goback.


[Migrated content. Thread originally posted on 19 January 2012]

I wan't to call a cobol program from c# and have two parameters which are defines as group elements.

Is there a way to call the cobol without writing a proxy program which then takes every single item into account?
I just wan't to give the cobol program a byte[] (sbyte[]) or a pointer to that array.

In java this is possible!

You could use a valuetype/struct and marshall this to/from it to a byte[], this would then feel more natural in the C# side.

For example here are some helper methods that will assist you in doing this:


    public T FromByteArray<T>(byte[] rawValue)
    {
        GCHandle handle = GCHandle.Alloc(rawValue, GCHandleType.Pinned);
        T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        handle.Free();
        return structure;
    }

    public byte[] ToByteArray(object value, int maxLength)
    {
        int rawsize = Marshal.SizeOf(value);
        byte[] rawdata = new byte[rawsize];
        GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
        Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(),false);
        handle.Free();

        if (maxLength < rawdata.Length)
        {
            byte[] temp = new byte[maxLength];
            Array.Copy(rawdata, temp, maxLength);
            return temp;
        }
        else
        {
            return rawdata;
        }
    }