|
F Hello Mike, Replies in-line marked with ==> Regards, Simon Coulter. «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«» «» FlyByNight Software AS/400 Technical Specialists «» «» Eclipse the competition - run your business on an IBM AS/400. «» «» «» «» Phone: +61 3 9419 0175 Mobile: +61 0411 091 400 «» «» Fax: +61 3 9419 0175 mailto: shc@flybynight.com.au «» «» «» «» Windoze should not be open at Warp speed. «» «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»
F-Mailer: Internet Mail Service (5.5.2650.21) Date: Sun, 25 Jun 00 22:26:37 -0400 From: "Pantzopoulos, Mike" <mikepantzopoulos@mynd.com> To: "'C400-L@midrange.com'" <C400-L@midrange.com> Reply-To: C400-L@midrange.com Subject: Dynamic Program
F couple of weeks ago I received some code snippets in reply to a problem I posted regarding dynamic program calls. Barbara Morris (thank you very much Barbara!) posted the original snippets. I'm yet to get a clean-compile but I wanted to post my interpretation of the code and was wondering if somebody could confirm or correct my thoughts please? Following is Barbara's code with my annotations in italics: #include <miptrnam.h> include files for prototypes.miptrnam holds the prototype for rslvsp. I tried making sense of the header files but could not. I did this to find where _Program comes from in the rslvsp function . ==> miptrnam.h just includes four other include files. _Program is defined in mih/miobjtyp.h in QSYSINC. #include <stdio.h> /*----------------------*/ /* typedef of a program */ /*----------------------*/ typedef void (somepgm_t)(int i, char *p); define the general form of the program that will eventually be called. I'm not sure what the correct terminology is, but I think this creates a template which the program eventually called has to map into? ==> More correctly, you are defining a prototype thus telling the compiler this function accepts an integer and a char pointer and returns nothing. The parentheses around the name 'somepgm_t' tells the compiler to treat this as a pointer to a function rather than a function. I would code it as: typedef void (*somepgm_t)(int i, char *p); to be more obvious but the compiler copes either way. #pragma linkage(somepgm_t, OS) defines a connection from somepgm_t to the operating system. OS means OS400? ==> OS means Operating System. It tells the compiler to prepare for a dynamic program call rather than a static function call. In RPG IV terms a CALL instead of CALLB. It behaves much like the EXTPGM keyword on an RPG IV prototype. int main(void) the main function in my program..... ==> The *ENTRY point of the program. Returns an integer and accepts no parameters. { somepgm_t * somepgm = NULL; the pointer (*somepgm) is of type somepgm_t and is set to NULL which I presume is a substitute value or a C keyword for all zeroes? Somepgm will later on be set to the system space address of the program I want to call. ==> NULL means the pointer has no address. It doesn't yet point to anything, it is just a place holder. Don't confuse it with a string of hexadecimal zeroes nor with the C libraries wierd idea of null-terminated strings, nor with NULL database fields. They are all different. You will later set the pointer to the address of the AS/400 program object. char pgmname[11] = "#JUNKLE"; this is the program name. In my program I can just have a string variable and populate it char libname[11] = "BMORRIS"; according to my own logic. I presume libname can be set to "*LIBL" ? ==> You are correct here. /*----------------------------*/ /* Get a system pointer to */ /* the program. */ /*----------------------------*/ somepgm = rslvsp (_Program, pgmname, libname, obtain the system space address of where the program held in the pgmname field is. _AUTH_OBJ_MGMT); I'm unsure where the _Program value comes from. Somepgm was declared earlier ==> Resolve the program object. That is, take the name of the object and resolve it to a virtual address. In the process check that you have object management rights to the program. _Program is a macro defined in the miobjtyp.h file that defines the internal object type (x'02') and subtype (X'01') of a program. You could also use WLI_PGM. The result is that 'somepgm' is no longer NULL but now addresses the program you named -- assuming such an object exists and you have the requested authority. You don't need *OBJMGT rights, only *USE. if (somepgm != NULL) If the address is not null then the function found the program and obtained the address { somepgm (5, "abcde"); therefore invoke it. The 'form' of the call is as per the typFdef earlier. ==> Yes. In my application I need to invoke a program which requires 3 parameters. Each parameter is in fact declared as an external DS via the #PRAGMA mapinc declaration. Do I therefore amend the typedef to look like ......typedef void(somepgm_t) (char *a, char *b, char *c)? where a,b, and c are the structure names assigned by the compiler? ==> Yes, but since the #PRAGMA mapinc creates typedefs you will need to allocate storage for the structures. You will also need to change the invocation to match the prototype. I'm sorry for making this sound complicated, but I thought it might be useful for others approaching C for the first time and used to RPG constructs, especially in the way that external AS/400 objects are made visible to a program. I've found a book called C For RPG Programmers but delivery is 4 weeks away. ==> If that is Jennifer Hamilton's book then (assuming it is based on the articles she published in News 3X/400 in September '91) it should be useful to you. Two other C books I have found useful are: A Book On C Al Kelley/Ira Pohl ISBN 0-8053-1677-9 This is useful tutorial type book. Mastering C Anthony Rudd ISBN 0-471-60820-3 This is more of a reference book. I chose these two out of the many thousands of C books because they discuss the hard stuff like signal handling, multiple processes, etc. Avoid any of the plethora of books that tell you signal handling is too advanced a topic -- they don't cover the other topics well either. You may also want the standard C book: The C Programming Language Brian Kernighan and Dennis Ritchie ISBN 0-13-110370-9 but this really takes some thinking to get the most out of it. Don't take what they say at face value. Mind you, these are the mongrels who inflicted C and Unix and many of the *nix tools on us. Thank You. ==> You're welcome.Title: Dynamic Program F!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
A couple of weeks ago I received some code snippets in reply to a problem I posted regarding dynamic program calls. Barbara Morris (thank you very much Barbara!) posted the original snippets. I'm yet to get a clean-compile but I wanted to post my interpretation of the code and was wondering if somebody could confirm or correct my thoughts please? Following is Barbara's code with my annotations in italics:
#include <miptrnam.h> include files for prototypes.miptrnam holds the prototype for rslvsp. I tried making sense of the header files but could not. I did this to find where _Program comes from in the rslvsp function .
#include <stdio.h>
/*----------------------*/
/* typedef of a program */
/*----------------------*/
typedef void (somepgm_t)(int i, char *p); define the general form of the program that will eventually be called. I'm not sure what the
correct terminology is, but I think this creates a template which the program eventually called has
has to map into?
#pragma linkage(somepgm_t, OS) defines a connection from somepgm_t to the operating system. OS means OS400?
int main(void) the main function in my program.....
{
somepgm_t * somepgm = NULL; the pointer (*somepgm) is of type somepgm_t and is set to NULL which I presume is
a substitute value or a C keyword for all zeroes? Somepgm will later on be set to the system space address of the program I want to call.
char pgmname[11] = "#JUNKLE"; this is the program name. In my program I can just have a string variable and populate it
char libname[11] = "BMORRIS"; according to my own logic. I presume libname can be set to "*LIBL" ?
/*----------------------------*/
/* Get a system pointer to */
/* the program. */
/*----------------------------*/
somepgm = rslvsp (_Program, pgmname, libname, obtain the system space address of where the program held in the pgmname field is.
_AUTH_OBJ_MGMT); I'm unsure where the _Program value comes from. Somepgm was declared earlier
if (somepgm != NULL) If the address is not null then the function found the program and obtained the address
{
somepgm (5, "abcde"); therefore invoke it. The 'form' of the call is as per the typedef earlier.
In my application I need to invoke a program which requires 3 parameters. Each parameter is in fact declared as an external DS via the #PRAGMA mapinc declaration. Do I therefore amend the typedef to look like ......typedef void(somepgm_t) (char *a, char *b, char *c)? where a,b, and c are the structure names assigned by the compiler?
I'm sorry for making this sound complicated, but I thought it might be useful for others approaching C for the first time and used to RPG constructs, especially in the way that external AS/400 objects are made visible to a program.
I've found a book called C For RPG Programmers but delivery is 4 weeks away.
Thank You.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.