Problem:
Creating COM objects has always been done using a COBOL class. However did you know you can expose a .NET managed COBOL program as a COM object?
How? Basically, you add a couple of class-attributes to any COBOL program that is compiled with the ILOBJECTIFY directive (which is the default in Net Express 5).
Resolution:
Here is a sample that shows how to expose a .NET managed "Hello World" COBOL program as a COM object. The sample comprises:
helloworld.cbl - the COBOL program
blddeliver.bat - builds the program as an assembly
bld.bat - puts the program in the Global Assembly Cache (GAC)
usehw.cbl - the test harness to try out the program
helloworld.cbl:
$set sourceformat"free"
program-id. Program1 as "HelloWorld".
environment division.
configuration section.
repository.
class cls-String as "System.String"
class ComVisible as "System.Runtime.InteropServices.ComVisibleAttribute"
class GuidAttribute as "System.Runtime.InteropServices.GuidAttribute"
.
class-attributes.
custom-attribute is ComVisible(true)
custom-attribute is GuidAttribute("794ABF7F-F5FA-35D8-81AB-637B677912AF")
.
data division.
linkage section.
01 lnk-value1 binary-long.
01 lnk-value2 binary-long.
01 lnk-getMessage cls-String.
procedure division.
goback.
entry "Add2" using by value lnk-value1, by value lnk-value2.
add lnk-value2 to lnk-value1
exit program returning lnk-value1.
entry "RetHelloMessage" using by reference lnk-getMessage
set lnk-getMessage to "Hello from Managed COBOL!"
exit program returning 0.
Tip: To generate the GUID to use for the custom-attribute above, use the uuidgen command (or the GUI equivalent, guidgen). At the Visual Studio command prompt, enter:
uuidgen -c
First, you build the program as an assembly so that it can be put in the Global Assembly Cache (GAC). Fortunately this can be done very quickly. Here is a little batch file to do this. It creates a strong name key for the program and then compiles the program.
blddeliver.bat:
if exist %1.key goto compileit
sn -k %1.key
:compileit
rem The following compile command must be on one line, but it's separated here for easy reading:
cobol %1.cbl verbose ilgen(sub) anim
ilversion"%2"
ilkeyfile "%1.key"
iltitle"%1 is our title"
ilproduct"%1 is our title"
ildescription"description for %1"
ilcompany"%1 is also our company name"
%3 %4 %5 %6 %7 %8 %9;
if errorlevel 1 goto failed
goto theend
:failed
echo ** Compilation failed.. **
:theend
I use a simple batch file to do the above and to put the program in the GAC:
bld.bat:
call blddllver HelloWorld 1:0:0:0 ilobjectify ;
gacutil /u HelloWorld.dll
regasm HelloWorld.dll /tlb
gacutil /i HelloWorld.dll
Next we need a test harness to try out the above program, so here it is:
usehw.cbl:
$set ooctrl( P)
program-id. usehw.
class-control.
cls-HelloWorld is class "$OLE$HelloWorld".
working-storage section.
01 helloWorld object reference value null.
01 item1 binary-long value 10.
01 item2 binary-long value 20.
01 result binary-long value 0.
01 HelloMessage pic x(80).
procedure division.
invoke cls-HelloWorld "new" returning helloWorld
invoke helloWorld "Add2"
using by value item1, by value item2
returning result
display item1 " " item2 "=" result
invoke helloWorld "RetHelloMessage" using
by reference HelloMessage
end-invoke
display HelloMessage
invoke HelloWorld "finalize" returning HelloWorld
exit program
stop run.
The test harness program can be compiled with:
cobol usehw.cbl int();
If everything has gone successfully you should see something like:
C:\\MyExample> run usehw
Micro Focus Net Express V5.000.0198
RUN TIME ENVIRONMENT Copyright (C) 1984-2006 Micro Focus (IP) Limited.
URN AXCGG/AA0/00000
0000000010 0000000020= 0000000030
Hello from Managed COBOL!



