Skip to main content

Problem:

The following error may occur if you are trying to invoke a C function from COBOL with NetExpress 5.0 and Visual Studio .Net 2005 (C) installed.  

"Runtime Error!

Program C:\\NetExpress5.0\\BAse\\Bin\\RUN.EXE

R6034

An Application has made an attempt to load the C runtime library incorrectly.

Please contact the application's support team for more information".

This error occurs when trying to set the entry point in the COBOL program as it tries to invoke an (exported) function of the DLL.

The C DLL is built from .obj files, linked together with link (v8 link). The .obj files are built , from the VS2005 command line, using cl.exe.

The problem occurs only when /MD is specified in the command line of cl.exe.

The problem does not occur on when running NetExpress 4.0 and Visual C Studio .NET 2003.

Resolution:

Consider the following commands being run from the VS2005 command prompt:

cobol caller.cbl,,,, GNT("caller.gnt")

cl -c /MD rout1.c

cl -c /MD rout2.c

link /DLL /OUT:routine.dll rout1.obj rout2.obj

run caller.gnt

caller.cbl simply calls rout1 and rout2.

caller.cbl is compiled, the c routines are then used to create the .obj files which in turn are linked into routine.dll.

/MD tells the compiler to reference the default standard VS2005 libraries in the generated code.

This compiles and links without error.

NOTE: as you're in the VS2005 command prompt, when building and running this test you'd need to run vcvarsall.bat x86, as recommended by KB24178, to set the PATH and LIB environment variables correctly for Net Express.  

The standard RUN.EXE is then used to start the application. However, the error occurs when trying to set the reference pointer to the .dll  (i.e: SET WS-DLL TO ENTRY 'ROUTINE.DLL' ).

The explanation of this behaviour and the way to resolve it is as follows:

C DLL's created using VS2005 require a manifest in order to locate the C runtime DLL. The manifest is created by the linker (e.g. routine.dll.manifest is created as a result of the 'link'). This then needs to be built into the DLL if that DLL is to be called from a non VS2005 executable

(eg run.exe).

To do that, after you've done the link you need to do the following from the VS2005 command prompt:

mt -manifest routine.dll.manifest -outputresource:routine.dll;2

This means the VS2005 C runtime libraries will now be used.

The COBOL programs used in this example is as follows:

       WORKING-STORAGE SECTION.

       01  WS-DLL      USAGE PROCEDURE-POINTER.

       PROCEDURE DIVISION.

       000-MAINLINE SECTION.

           DISPLAY 'ABOUT TO CALL ROUTINE'.  

           SET WS-DLL TO ENTRY 'ROUTINE.DLL'

           CALL 'ROUTINE1'.

           DISPLAY 'ROUTINE CALLED'.  

         STOP RUN.

rout1.c

#include <windows.h>

#include <stdio.h>

__declspec(dllexport) routine1()

{

printf("HELLO THERE 1 \\n");

}

__declspec(dllexport) routine2()

{

printf("HELLO THERE 2 \\n");

}

main()

{

routine1();

routine2();

}

Old KB# 1530