Highlighted
Absent Member.
Absent Member.
2991 views

[archive] Calling Cobol from C++

[Migrated content. Thread originally posted on 25 November 2002]

I have a task that need to call Cobol from c++ program. How can I do it?

According to the manual of AcuCobol 4.2. It have a little bit information about calling Cobol function from C++ only. Is there have a detailed technical information about this task?

Thank you.
0 Likes
5 Replies
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling Cobol from C++

The best way to do this is to use AcuGT Automation server. This is a COM object which provides you an interface to execute COBOL objects. In the sample directory of ACUCOBOL-GT, there is a directory named autosrv. These samples you will find here are how to call Cobol from Visual Basic, but I doubt you would have problems understanding them with background from C++.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling Cobol from C++

I've spent the last couple of days researching that very question. It turns out to be rather complex. There are a couple of different routes to interoperability with C/C++. Generally, it is much easier to call C/C++ from cobol than vice-versa. There are two very easy methods for calling C from cobol, via the direct interface, and loading program libraries via dll/so. In either case, AcuCorp's documentation is pretty good.

The most important thing to remember is that, unlike C, cobol is not a linked language and the object files produced by the compiler are not directly executable code. Cobol programs are managed by the AcuCobol runtime (wrun32.dll) and not your calling executable. In windows, (and I am not 100% sure about this) cobol programs are always stared up in a seperate process when calling through the cobol calling interface (there are two versions of this, the dll interface and the autmation server). It is not directly clear at this point of the spawned cobol programs are considered a child process or not. In any case it is most likely difficult or impossible to share memory with the cobol app without C code on both sides of the equation (i.e. a relinked runtime). In most cases, you can't pass a pointer between processes, generally in windows you use messages for signaling and memory mapped files for data transfer.

If you are like me, you started looking at the automation approach as a way of incorporating cobol programs into a C application. This should work ok for non-visual cobol programs which communicate with your app via inputs/outputs in the call. Most likely you will run into problems if you try to transfer data which is not explicitly contained in the the passed parameter (pointers). Calling GUI based cobol programs using the automation approach will pop up a new window and place another icon on the task bar. Most likely you want to avoid this.

Another approach to C/Cobol mixed development is to subclass the the runtime application window. This is both the most powerful and the most complex approach, because you have to know how to construct a win32 app from scratch. The short version is that you now have power to handle windows messages before the runtime sees them (including user messges) for IPC from other apps and should also allow you to draw directly on the rutime window. Also, you can supress/alter user input before the cobol program sees it. In this case, (in theory) you can alter the behavior of the runtime in such a way that you can accomplish almost anything. Note that I've never done this, and there is no ducumentation on it.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling Cobol from C++

MerlinM,

you are very much on the track of something here. I wasn't aware that it really was a question about having a communication path going on between the cobol app and the hosting C++ app. But you can accomplish this with the AcuGT Automation server. What you have to keep in mind is that the parameters you pass in to your cobol application are global variants, e.g. this memory area is in fact shared between the AcuGT server and your app.

Problem is, there are no semaphore basics in there, so you will have to tweak your own.

So, say that you passed four parameters along with your cobol application, the first being the data buffer in, the second being the signal in, and the third data buffer out and the fourth would be the signal out.

Assuming it is up and running, both the Acugt and the container would then enter 'listen' mode, that is, they would look at respectively the signal in and signal out. Assume that they are both initialized to 0, then, when the container had something to send in, it would place the data in datain, and set the content of signalin to 1. The cobol app would in its wait state determine that signalin changed to 1, thus grabbing the content of datain and setting signalin to 0, sort of indicating that it got its stuff.

It would now process whatever it was supposed to, place the result set in dataout, and set signalout to 1, eventually going back to the loop waiting for further instructions.

In cobol, you would use C$SETVARIANT and C$GETVARIANT to inquire/modify the content of the params being passed, and you would probably put in a timer to avoid hogging resources of the hosting computer, as you would in the container.

Giving this a second thought, it might be an idea to add an event to the AcuGT in this sense, which could be fired from the cobol app to signal to its outside, that there are data. Hm... Gotta think about that.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling Cobol from C++

Well, after more thought and experimentation on the subject I am not sure that IPC communcation over the automation server is the easiest or the best approach.

The biggest problem with IPC communcation over variants is the danger of sending a pointer to memory inside the variant. While the variants are streamed, and pointer safe, the internal contents of them are not. Since unstreaming an object streamed in a C++ app is tedious and difficult, this would not be my first choice for IPC unless nothing else was available (note, with xml services in AcuCobol , this would be a different story...could serialize objects with DOM). I would perfer just to write stuff out to files.

The fact that using the automation server starts up a separate process negates most of the advantages of interoperability. In fact, it is better than clicking the icon on the desktop (wrun32.exe -c ...) in one respect only: you can retrieve the results of the call and do something with it. This is not helpful to me and probably most people because we are trying to integrate C/C++ functionality into legacy enterprise apps. Without real shared memory (external data objects), it is just not worth the benefit. In my particular case, I am trying figure out the best way to add windows functionality to a text based accounting app.

Subclassing the cobol runtime might fix that problem. If the cobol runtime run with a substituted messge handler, I could do IPC via user defined messges (RegisterWindowsMessge) and MemoryMappedFIles. Note that this is more work than simply passing pointers around the process.

Looking at it from the other direction, AcuCobol has a very elegent way of calling C functions via DLLs. When using this method, I can pass memory between cobol and C just fine. What I am missing is a way for the C program inside the DLL to call non-visual cobol routines In the Same Process. If I had that, I would use windows apps for screen presentation to call my non-visual data processing logic. I am experimenting with cobol() and cobol_exit_code(), but so far have not gotten them to work the way I want. My dream would be to have these functions run in the same process as the original cobol calling routine. In other words:
1. cobol program calls C DLL which pops up data entry form
2 C DLL accepts input but needs to run some validation vs. the data, so calls cobol("validate", n, args)
3. C program completes and returns process control to wrun32.dll

AcuCorps' visual interface editor is pretty nice but I miss several features from C, particularly string processing. In any case, I perfer Delphi/C++ Builder.

I had some success tying in 3rd party report products with AcuCobol via DLL communication, and some other simple non-visual stuff (qsort, dynamic buffers). But I want more 🙂

With full C/Cobol interop I would do two things in very short order (neither being much work if I could call I$IO routine directly from a C program):
1. implement TDataSet interface in Delphi
2. write a data adapter for data services in ADO.net
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: [archive] Calling Cobol from C++

> with xml services in AcuCobol , this would be a different story...

Well, with the upcoming 6.0 you will get both web services and xml at your service.

> If the cobol runtime run with a substituted messge handler,
> I could do IPC via user defined messges
> (RegisterWindowsMessge) and MemoryMappedFIles.

You don't have to subclass to do that. You can listen for any message you want today using GetMessage and the related functions, and then act upon their content.

> Note that this is more work than simply passing pointers
> around the process.

In the first place yes, but then, once you got the basic framework rolling...

> What I am missing is a way for the C program inside the DLL
> to call non-visual cobol routines In the Same Process.

As long as we have no capability to provide callback procedure pointers this won't be easily solved. Note that I am not saying
it is impossible, but you would certainly have to tweak it a bit.

> I would use windows apps for screen presentation to call
> my non-visual data processing logic.

If you had your window app implemented as activex, you could also provide it with events, in which you could put the process you wanted executed and in which you could return the resultset free of choice. Why don't you do that?

> 1. cobol program calls C DLL which pops up data entry form

E.g. corresponding to what I said above, think ocx instead of dll. That will give you the flexibility you want and at the same time providing access to the business logic and also providing a safe way of IPC.

> 2 C DLL accepts input but needs to run some validation vs.
> the data, 3. C program completes and returns process control
> to wrun32.dll

Implementing your form as an activex with events would make it coop gracefully with the runtime as you describe here.

> from C, particularly string processing.

Can't blame you. Both Delphi and C, in particular C++ has very strong string handling routines. Albeit INSPECT and STRING, UNSTRING has a lot of options it does not meet those standards. When that is said, nor is string handling what COBOL were made for.

> But I want more

Are you sure? 🙂

> (neither being much work if I could call I$IO
> routine directly from a C program):

You can do that, who says you can't?

> 1. implement TDataSet interface in Delphi
> 2. write a data adapter for data services in ADO.net

Sounds interesting, but why don't you just hook into AcuODBC? In that case you would even benefit from the AcuOBDC Server and the performance gain in it.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.