Skip to main content

[archive] calling cobol from .net

  • March 7, 2008
  • 11 replies
  • 0 views

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?

11 replies

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Hi,

We have been trying (Most unsuccesfully) to call a cobol program from .NET.
We have used 7.0,7.2 and 8.0. We first tried the first known method which uses the ACUGT COM object (This requires the C$GETVARIANT), this used to work fine but when we try and call it from .NET we always get a COM Exception error, cannot work it out, I have tried all perrmissions etc with no success. We then tried using the wrunnet.dll in version 8.0 and we kept getting MAV's. we then moved on to using the -netdll compiler option, we have had limited success with this. We have a simple program that had a 1 MB string in the linkage section and procedure division using (note DO NOT USE C$GETVARIANT) as the string is passed in by reference. (we had to use the .NET stringbuilder function to construct a 1MB string as the program is passing back more information in this string than what it receives. This appears to work the first time bu fails every other time, and only restarting IIS6 does it work again. We have even implemented the 'system.web.httpruntime.unloadappdomain()' while it terminates the application it still doesn't work after the first time. by the way the .NET app that we have written is a .NET webservice which passes an XML string and the cobol program processes this string and sends it back. This is also using .NET framework 2.0

All in all I have not been able to confidently setup any .NET environment that works for any version of AcuCobol.

Does anyone have any ideas of what could be happening?

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Can you post your .Net code?

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Have you tried the example that is in C:\\Program Files\\Acucorp\\Acucbl800\\AcuGT\\sample\\dotnet\\nettoacucobol

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Yes we have, and it fails, I cannot get any of the example .NET programs to work. COM fails, .NET 1.1 fails, .NET 2.0 Fails, wrunnet.dll Fails, --netdll fails. Acucorp need to provide better working examples (ones that work). The documentation for the .Netdll's is rather sparse and misleading. Why when I use the --netdll option does it generate the CVM.dll module only when I have specific PIC clause specfied in the linkage area. If I specify a handle (ie using the c$getvariant) it does not generate the CVM.dll, it only genetares the base.dll and tge .netmodule. Is this base.dll usable anywhere? if this is the case then why not issue a compiler error saying that you cannot use pointers/handles in linkage when using the --netdll option.

However, when we use the CVM.dll in .NET we get "Attempted to read or write protected memory. This is often an indication that other memory is corrupt" on the second time we call it. MSDN reports that this is because we are using unmanaged code and we are passing variables by value as opposed to by reference. The .NET module is passing by reference.

What am I doing wrong

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Two things I would check with you. Go to the bin directory of your Acu installation and execute the following:
regasm AcuToNet.dll
Marshal /register

If that does not help, search your registry to AcuToNet (data) and Marshal (data), verify the filepaths you find. If they do not match the bin directory from wish you just tried to register, you may want to try modify this manually.

The AcuToNet is required for the communication from Acu to .NET, the Marshal is for the communication from .NET to Acu.

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Thanks, I;ll look, but wouldn't that mean that the .NET to Acu would not work at all? The application works perfectly the first time, and fails the second time and subsequent times, we have to restart IIS.

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
True, I figure you should send your case to Tech support. Somethings odd.

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Something is very odd indeed. We have now gone about it another way. We have successfully created a .NET web service which uses remoting to a .NET window service which calls the AcuGT Automation server directly. This effectively bypasses the need for the .NET Acu Interface and aslo bypasses the issues we were haveing with our XML parser (See other thread on C$XML) using AcuConnect.

Regards

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
Good work! :-)

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
We have found that the command to register the Marshal server is:

Marshal /regserver

To unregister it, use

Marshal /unregserver

[Migrated content. Thread originally posted on 22 March 2007]

Version 7.2 gives a couple of ways to do this. Anyone with any experience with this? Which method did you use? We are trying to use wrunnet.dll method and we can get the cobol program to be called but when C$GETVARIANT is used to convert a variant to a PIC XX field it returns "missing parameters". We are thinking about trying the compile option --netdll next. Any suggestions?
I've been able to get the code below to work, but I can't honestly say what I may have had to setup to get it to work (all it does it launch our main application so I can debug some printing code I wrote in VB.NET that gets called from the COBOL).


Imports acucobol
Public Class StartupScreen
   PrivateShared COBOL As CVM
   PrivateShared ErrCode As errorTypes
   PrivateShared ReturnCode AsInteger = 0

   Private Sub StartButton_Click(ByVal sender AsObject, ByVal e As System.EventArgs) Handles StartButton.Click
      Launch()
   End Sub

   Private Sub Launch()
      Me.Hide()
      Try
         COBOL = New CVM
         COBOL.ConfigFile = "..\\etc\\cblconfi"
         My.Settings.DebugMode = DebugCheckBox.Checked
         COBOL.Debug = My.Settings.DebugMode
         COBOL.ExtendedError = True
         COBOL.RunPath = "..\\Bin"
         COBOL.NoStop = True
         Dim CBLThread AsNew Threading.Thread(AddressOf StartCF)
         CBLThread.Name = "CFThread"
         CBLThread.Start()
         CBLThread.Join()
      Catch ex As Exception
         MsgBox(ex.ToString)
      End Try
   End Sub

   Sub StartCF()
      ErrCode = COBOL.Call("WCFMAIN", Nothing, Nothing, "", ReturnCode)
      If ErrCode <> errorTypes.CS_OK Then
         MessageBox.Show("The Error Returned Is Below:" & vbCrLf & ErrCode.ToString, "There Was A Problem Running STRUCTURE", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End If
   End Sub
End Class


I do remember having quite a bit of trouble getting this (and the reverse, calling .NET from COBOL) to work properly in the beginning. The documentation and customer support were of esentially no help at all.

-Chris

On Edit: This VB.NET form is run from the "Bin" directory, which lives inside our main application directory. It is esentially a copy of the "BIN" directory with the Acu-GT runtime in it. Also inside our main application directory is the "ETC" directory with the CBLCONFI file in it. Before attempting to make a program like this work, make sure you can get the program to run correctly from the command line (in this case, from a command prompt in the "BIN" directory, you should be able to type in "wrun32.exe -c ..\\etc\\cblconfi WCFMAIN" and have the "WCFMAIN" program run successfully.

Other items I believe needed to be done beforehand:
1: From the .NET directory (ie: %SYSTEMROOT%\\Microsoft.NET\\Framework\\v2.0.50727) you should run regasm.exe on the acutonet.dll and wrunnet.dll files.
2: You may need to "TRUST" the location of the assembly you're planning to run (also from the .NET directory, run a command like "caspol -m -q -addgroup 1.2 -url http://file:///J:\\* FullTrust -n AcuCorp-Drive"). This will apply to mapped network drives, and probably UNC paths.
3: The location of the assembly MUST be in either the "Computer" or "Local Intranet" zones when opened through Windows Explorer (look in the Status Bar at the bottom of the explorer window). If it comes up as "Internet", the .NET Framework will not run your program, or give you any kind of useful error.
4: If the assembly is in a location addressed by IP address or FQDN (ie: \\\\192.168.1.101\\share or \\\\server.domain.com\\share ), it will NOT work, even if the other rules are met. Ask Bill Gates why....

To keep things simple, it's better to setup a directory on C: to test from, so you don't have to mess with items 2, 3, and 4.