                       Using Registration-Free COM 
                            with Visual COBOL
                                README


In order to use Registration-free COM to call a managed code assembly from a 
native code executable you need to create an Application Manifest file for the 
native program and an Assembly Manifest file for the managed assembly. These
are simple text files that can be created with an editor such as Notepad.

In the demo VCCOMServer.sln there are two projects. The VCCOMServer project is the .NET 
Class library that will be called by the native program.

It contains the following code defining an interface definition called
IVCCOMServer and the actual class VCCOMServer.VCCOMServer.

       id division.
       interface-id. InterfaceDef as "IVCCOMServer".
           
       method-id. testVCstring public.
       local-storage section.       
       procedure division using lnkString as string.
       end method.
       
       method-id testVCint public.
       local-storage section.
       procedure division using lnkInt as binary-long.
       end method.
       
       method-id testVCFloat public.
       local-storage section.
       procedure division using lnkFloat as float-long.
       end method.
       
       method-id testVCGroup public.
       local-storage section.
       procedure division using lnkString as string.
       end method.    
       
       end interface InterfaceDef.

      ***  Starts actual Class implementation
       
       class-id VCCOMServer.VCCOMServer implements type IVCCOMServer.
       
       method-id testVCstring.
       local-storage section.
       procedure division using lnkString as string.
	       move "From method testVCstring" to lnkString
           goback.
       end method.

       method-id testVCint public.
       local-storage section.
       procedure division using lnkInt as binary-long.
           move 50 to lnkInt
           goback.
       end method.
       
       method-id testVCFloat public.
       local-storage section.
       procedure division using lnkFloat as float-long.
           move 123.75 to lnkFloat
           goback.
       end method.
       
       method-id testVCGroup public.
       local-storage section.
       01 lnkGroup.
          05 lnkName    pic x(20).
          05 lnkCompany pic x(20).
          05 lnkInteger pic x(4) comp-5.
          05 lnkDecimal pic s9(4)v99.
       linkage section.
       procedure division using lnkString as string.
           
           move "Chris Glazier" to lnkName
           move "Micro Focus" to lnkCompany
           move 20 to lnkInteger
           move -987.12 to lnkDecimal
           set lnkString to lnkGroup
           goback.
       end method.    
       end class.

This project is set to be registered for use with COM Interop by 
double-clicking on the VCCOMServer Properties within Solution Explorer
and navigating to the COBOL tab, clicking the Advanced button and checking
the Register for COM interop checkbox. After rebuilding the project this
will register the assembly as COM on the development system and will
create the type library file VCCOMServer.tlb in the output folder.

The Assembly Manifest file for the assembly VCCOMServer.dll is named
VCCOMServer.Manifest and it should be added to the VCCOMServer project
and it's Copy to Output Folder property must be set to Copy Always or Copy 
if Newer. The Assembly Manifest files must always have the name as the 
assembly with the extension .Manifest and they must be in the same folder 
as the assembly they reference.

The contents of this file are:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">

<assemblyIdentity name="VCCOMServer" version="1.0.0.0" type="win32" processorArchitecture="x86"/>

<clrClass
   name="VCCOMServer.VCCOMServer"
   clsid="{87F920EF-4CD8-35AA-BAED-B08E0F9FBC43}"
   progid="VCCOMServer.VCCOMServer"
   runtimeVersion="v4.0.30319"
   threadingModel="Both"/>

<file name="VCCOMServer.tlb">
 <typelib
     tlbid="{21E4612F-FFDC-352B-82E0-2304B104660B}"
     version="1.0"
     helpdir=""
     flags="hasdiskimage"/>
</file>

When creating your own Assembly Manifest files you can use this as a template.
You would have to provide your own unique values for several of the fields
in this file.

<assemblyIdentity name="VCCOMServer"
Use your own base name for your managed .dll.

name="VCCOMServer.VCCOMServer"
Use your own class name specified in the Class-ID of your COBOL class.

<file name="VCCOMServer.tlb">
Use your own Type Library name

For:
clsid="{87F920EF-4CD8-35AA-BAED-B08E0F9FBC43}"
tlbid="{21E4612F-FFDC-352B-82E0-2304B104660B}"

You can find out these values by running the tool oleview from a Visual Studio
Developers prompt.

From the Start menu navigate to All Programs-->Visual Studio 2015-->
Visual Studio Tools and open Developer Command Prompt for VS2015.
From the command prompt enter the command 
   oleview
to start the oleviewer tool.
In oleviewer click on File-->View Typelib and navigate to your projects
output folder and select the .tlb file created. In this demo that would
be in VCCOMServer\bin\x86\debug\VCCOMServer.tlb.

The clsid string value can be found under the section containing:
coclass VCCOMServer 

The value to use would be:
uuid(87F920EF-4CD8-35AA-BAED-B08E0F9FBC43)

The tlbid string value can be found under the section containing
typelib filename: <could not determine filename>

The value to use would be:
uuid(21E4612F-FFDC-352B-82E0-2304B104660B)

All other values can stay the same as long as your assembly and native
program are compiled to the x86 platform target.
--------------
The second project in the solution is VCCOMClient which will produce a
native executable file caled VCCOMClient.exe.


      $set ooctrl(+p)
       id division.
       program-id.  VCCOMClient.
       class-control.
           VCCOMServer is class "$OLE$VCCOMServer.VCCOMServer".
       working-storage section.
       01 anInstance    object reference.                             
       01 aString       pic x(50)   value spaces.                     
       01 anInteger     pic x(4) comp-5   value 0.                    
       01 aFloat        comp-2 value 0.                               
       01 aGroup.                                                     
          05 CustName    pic x(20).                                   
          05 CustCompany pic x(20).                                   
          05 CustInteger pic x(4) comp-5.                             
          05 CustDecimal pic s9(4)v99.                                
                                                                      
       procedure division.                                            
                                                                      
           invoke VCCOMServer "new" returning anInstance              
           invoke anInstance "testVCstring" using aString             
           display aString                                            
                                                                      
           invoke anInstance "testVCint" using anInteger              
           display anInteger                                          
                                                                      
           invoke anInstance "testVCFloat" using aFloat               
           display aFloat                                             
                                                                      
           invoke anInstance "testVCGroup" using aGroup               
           display CustName                                           
           display CustCompany                                        
           display CustInteger                                        
           display CustDecimal                                        
                                                                      
           stop run.

The Application Assembly for this project is called VCCOMClient.exe.manifest
and it should be added to the VCCOMClient project and it's Copy to 
Output Folder property must be set to Copy Always or Copy if newer. The 
Application Manifest files must always have the name of the executable program on 
disk including the .exe extension with an additional extension of .manifest added 
to the name. The Application Manifest must be in the same folder as the executable 
program they reference.

The contents of this file are:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">

<assemblyIdentity name="VCCOMClient.exe" version="0.0.0.0" type="win32" processorArchitecture="x86"/>

<dependency>
 <dependentAssembly>
  <assemblyIdentity name="VCCOMServer" version="1.0.0.0" type="win32" processorArchitecture="x86"/>
 </dependentAssembly>
</dependency>

</assembly>

When creating your own Application Manifest files you can use this as a template.
You would have to provide your own unique values for several of the fields
in this file.

<assemblyIdentity name="VCCOMClient.exe"
Change this to the name of your own executable file.

<assemblyIdentity name="VCCOMServer"
Change this to the name of your own .NET assembly that you will be calling.

If you build the project it should create the native client, the managed assembly,
The type library and both of the manifest files in the common output folder.

If you deploy this to a computer on which COBOL Server has been installed
and licensed then you should be able to run this with no need to register the 
.NET assembly first.


