Has anyone involved in writing DLL using COBOL.
I just referred the "DLL Programmer’s Guide for TNS/E Systems" manual
to know more about creating DLL. I could see an example using C
language. Can this be done using COBOL ?
My requirement would be as as below :
Main program would use a DLL to pathsend a request to a server.
Thanks
Did you look in the manual "HP COBOL Manual for TNS/E Programs"?
I have not created any DLLs in COBOL, but there are directions in chapter 13 of the manual about how to do it. Just looking at what the COBOL manual describes there, it seems like it is not very difficult. If you have trouble getting it to work, post the details of what is giving you trouble, and we will try to help.
Good luck!
Just a question: Is the requirement to do pathsends only? You don't
need a DLL to do that. If it's to multithread pathsends, that's going
to be a bit scary in both COBOL and using DLL.
The requirement seems to me to be quite counter-intuitive. Of course,
not knowing why a DLL is so important to your application, I could be
wrong.
Pathway does a good job of managing services in the form of Pathway
Servers. Simply move would be DLL code into a server and you're all
set.
Without any other information, this is purely a guess, but I imagine the motivation is that they want to put the statements that do the Pathsend into a library, probably either to isolate the system-dependent stuff for better portability, to make it easier to adjust the interface to the servers, or so they don't have to teach all their programmers how to write Pathsend calls.
Using a DLL for the library routines is better than binding the library code at build time in that the library can be changed and the change be effective without rebuilding all the programs that use the library.
Yes Keith. Thats exactly the reason behind creating DLL. I would build
some standard routines as DLL. All the other programs would use this
DLL to get their information. In case of modification to DLL we need
not recompile all the programs.
Thanks for confirming that my guess was correct.
Did the descriptions in the COBOL manual that I mentioned help you get your library to work?
No Keith. I couldnt find the information from the cobol manual..
You did not find what you needed in the "HP COBOL Manual for TNS/E Programs"? I just checked, and I was quoting from an older copy of the manual that I had on my computer. The current version of the manual, dated February 2011, that I just fetched from www.hp.com/go/nonstop-docs, has the information in chapter 14, "Libraries and Utility Routines" in a subheading named "Dynamic Link Libraries (DLLs)" (not chapter 13 as I quoted earlier).
I believe that section will tell you all you need to know in order to create a DLL from your COBOL subprograms. I have never done it myself, but it appears to be very easy, unless what is written there is not the whole story. If you do not find that chapter in the manual or the instructions there do not work for you, post again describing what problem you have encountered and we will try to help you solve it.
I need to know the cobol equivalent for functions like dlopen(),
dlsym(), dlclose() etc. I was referring the "C" program in DLL manual.
Would like to know the COBOL equivalent of that.In COBOL manual I
could see steps for compiling and linking the DLL. But couldn't find
an example in COBOL.
C Program that I was referring :
#include <dlfcn.h>
#include <stdio.h> nolist
/***********************************************************
| main:
|
\***********************************************************/
int main(int argc, char *argv[]) {
int result = 0;
union {
int resCode;
short err[2];
} res;
typedef void (*HelloFPtr)(void);
HelloFPtr pHello;
dlHandle dlopenHandle;
dlopenHandle = dlopen("hellodll",RTLD_NOW);
if (dlopenHandle == 0) {
printf( "%s\n", dlerror( ) );
return (1);
}
pHello = (HelloFPtr)dlsym(dlopenHandle, "hello");
if (pHello == 0) {
printf( "%s\n", dlerror( ) );
return (2);
}
pHello( );
result = dlclose(dlopenHandle);
dlopenHandle = 0;
/* demonstrate the error routines */
dlopenHandle = dlopen("NotThere",RTLD_NOW);
if (dlopenHandle == 0) {
res.resCode = dlresultcode( );
printf("dlopen of a non-existent dll returns result %i\n"
,res.resCode);
printf("\terror( %i,%i)\n"
,res.err[0], res.err[1]);
printf( "%s\n", dlerror( ) );
return (1);
}
return 0;
} /* of proc main */
The source code for helloc is as follows:
#include <stdio.h> nolist
void hello( ) {
printf("Hello, I am a DLL!\n");
}
Here is what understood from the DLL manual :
Following are the steps to compile and build a DLL :
1. Main program name : mainc 2. DLL source name :
helloc
Main program object name : maino DLL object name : helloo
Step 1 : Compile main program and produce the object : (NMC for TNS/R
whereas ccomp for TNS/E)
NMC /IN mainc/maino;suppress,OPTIMIZE 0,SYMBOLS,ERRORS
5,EXTENSIONS,call_shared
Note : call_shared is an important compiler directive in the above
command.
Step 2: Compile the DLL source and produce the object :
NMC /IN helloc/helloo;suppress, OPTIMIZE 0,SYMBOLS,ERRORS
5,EXTENSIONS,call_shared
Note : call_shared is an important compiler directive in the above
command.
Step 3: Create the DLL using the ld utility. (Use eld for TNS/E
systems)
ld helloo -o hellodll -obey $SYSTEM.SYSTEM.libcobey -L $OSS.NSKAPAT4 -
shared -export_all
Note : -export_all option is important
DLL name : hellodll will be created in $OSS.NSKAPAT4 location
Step 4: Build the final object file (i.e. link the DLL to the main
program)
ld maino -o mainexe -obey $SYSTEM.SYSTEM.libcobey -L $OSS.NSKAPAT4
$SYSTEM.SYSTEM.CCPPMAIN -l ZRLDSRL
Note : above command allows the "mainexe" to use load DLL present in
$OSS.NSKAPAT4 location during the run time.
Following is my understanding on the functions used for dynamic
loading of routines :
There are 5 C functions :
1. dlopen()
Accepts 2 parameters. And returns a return code of type "dlHandle". If
return code is zero it means error occurred.
Parameter 1 : dll name (In our example it is "hellodll")
Parameter 2 : There are different modes in which we can open the DLL.
RTLD_NOW is used in our example and it links the newly loaded library
immediately
2. dlsym()
Accepts 2 parameters.
Parameter 1 : dlHandle value returned while using dlOpen()
Parameter 2 : Symbol name or the routine name which we need to access
from the main program
The dlsym function obtains the address of an external symbol in a DLL
3. dlclose() - Use to unload DLL
4. dlerror() - Used for error handling
5. dlresultcode() - Used for error handling
There might be a way to use those procedures from a COBOL program, but are you sure you really need to do so? I believe they are needed only if you must control loading of the DLL dynamically at run time. That is, if you need to make the program that uses the library only load the DLL under certain conditions.
If it would be acceptable for the program to load the library when the program starts, then you do not have to use any of those procedures. You just link the program with the DLL as described in the portion of the COBOL manual I mentioned, and each time the program is started, it will load the current version of the DLL. If you change the DLL, the next time you start the program, it will use the new version of the DLL. Is that sufficient to meet your needs?
While I have built and used Cobol DLLs I never had the need to use the
Dynamic invocation. To my knowledge this feature is only available to
C/C++ and pTAL languages. You could of course write a C DLL that then
invokes these calls to process your Cobol DLL! ;^).
Agreed, mustlearn. But, since the OP does not seem to be proficient
in COBOL, why are we encouraging him to write a COBOL DLL?
If you look at the manual, you'll see that writing a COBOL DLL is no different than writing any other COBOL subprogram. What makes it a DLL is only some compiler options you select. And if you allow the system to load the DLL automatically, rather than doing loading on demand that he thought was necessary, using the DLL is very little different than linking to a regular separately-compiled COBOL subprogram.
So I do not believe we are encouraging him to do anything that is harder than using normal COBOL subprograms. At least I'm not encouraging that.
If his application is such that he really does need to have the DLL not load until explicitly requested, that might be something that is very tricky in COBOL (I don't know -- I haven't investigated that yet), but if his application requires that, then he'll need to learn how to do that. I have a feeling that he does not need the load on demand feature of DLLs, so he probably does not need to do anything difficult at all.
I agree Keith.
But, my point is this: doing a simple Pathsend call to a server is a
whole lot easier than trying to multitask through a DLL. Maybe I'm
missing something here.
In other words, isolating the supposedly "volatile" code to a single
Pathway server does exactly the same as isolating it in a DLL. The
plus side is that Pathway takes care of all load balancing and
synchronization.
I just don't see the DLL benefit here. Maybe I don't get the
requirements yet...
Jayaganesh, the original poster, never said anything about multithreading. That was something that Randall said, for some reason, without any basis in what Jayaganesh said.
Also, Jayaganesh confirmed my guess about why they want to use a DLL -- so that they can change the library without rebuilding all of the programs that use the library. I think that is a perfectly good reason for wanting to use DLLs. He or she did not say why they want to be able to change the library, but they do. He or she said nothing about doing load balancing or synchronization in the DLL. Simply that the Pathsend call would be in the DLL. I ventured some guesses about why they might want to put the Pathsend calls in a library. Jayaganesh did not say whether any of those reasons was what is motivating them to use a library rather than coding the Pathsend calls inline, but they have some reason for wanting to isolate the Pathsends into a library. Once they take the approach of using a library, for any code, then wanting to take advantage of DLLs so that they don't have to rebuild the programs when the library changes seems like a good choice to me.
Keith, I was trying to figure out why someone would want to use DLL's
from COBOL and point out that there are inherent issues using DLLs in
your own multithreaded code. With that said, it seems, from the
Jayaganesh's thread, that the following requirements are going on:
1. Call DLL from COBOL.
2. Dynamically load/select which DLL is being used (the need to call
dlopen()).
3. Isolate platform specifics in the DLL.
4. DLL code itself may or may not contain COBOL.
Personally, I think this is an excessively complex and specific set of
requirements to cover a relatively simple need to isolate platform
specific. Assuming that the platform specifics don't have to be in
COBOL, I'd write those in C and call them from COBOL. If, for some
reason you need to refactor the C code into multiple layers of DLLs,
you can do that in a much more flexible DLL structure (with more
people out there who know how to do it, therefore more sustainable).
If there is a requirement to call dlopen() for the purpose of
dynamically choosing the DLL is in there, I'd be suspicious of the
architecture. You can set up runtime search paths for your DLL to deal
with that and avoid dlopen() altogether - that's in the manual, of
course.
Remember other platforms may not support COBOL DLLs. I wouldn't accept
a design based on the above discussion to support independent COBOL
that had hard DLL requirements.
So, to enumerate satisfying the requirements:
1. Call C-based libraries from COBOL.
2. The C libraries can call SERVERCLASS_SEND_ to get to code in
Pathway server, if needed.
3. The C libraries can be simple DLLs to get to the first level
platform code invoked by the loader set up by standard options
discussed above.
4. The C libraries can further invoke any complex DLL structures based
on dynamic loading for other more involved platform code.
DLL is NOT a good approach to load balancing on the NonStop. As your
program structure grows, you will want to partition the capabilities
into services that can be balanced. Provision for that (#2). The COBOL
code doesn't need to/shouldn't interact at this level, if you plan on
a future port/share of the code. If you don't play on a future port/
share, the discussion is pretty much moot.
I think it is likely that Jayaganesh did not understand that it is not always necessary to use dlopen() and dlsym() in order to use a DLL. The "DLL Programmer’s Guide for TNS/E Systems" manual that he or she mentions in the first post probably concentrates on the mechanics of using those procedures because they are a bit complex, and either fails to mention the automatic case or does not emphasize it clearly enough. I have not read that manual, so I don't know how well it describes the automatic case.
He or she has not mentioned the need to choose among multiple libraries at run time, do load balancing, or any other tricky stuff. He or she has only said that they want to use DLLs so that they may make a change to the library without rebuilding all the programs that use the library.
If that really is all they want to do, using a COBOL DLL that gets automatically loaded when the program is started seems like a nice, simple, appropriate approach.
If I misunderstand and Jayaganesh actually wants to do the sort of complex stuff you refer to, I also would call the approach into question, but nothing Jayaganesh has said leads me to believe they want to do anything like what you are talking about.
As primary goal was to avoid rebuilding of main programs, I would go
with loading the DLL during the startup instead of dynamic loading of
the DLL.However in case of dynamic loading of DLL, as you guys
mentioned we can call C based library instead of COBOL as we are not
sure whether we can achieve the dynamic loading of DLL via COBOL code.