|
"Dan Bale" <dbale@genfast.com> wrote: > > Colin & Scott, > > Scott, wow!!! That was a beautiful piece of work you did in that la > email, I > really appreciate the effort you made to explain everything. I'm > still trying > to get a handle on the pointer thingy, but that will take some > practice, I'm Yes, pointers are a a bit confusing at first. My philosophy for understanding them is this: 1) What is a variable to the system? Its a convienient name used by a programmer to reference an area of memory, and what type of data can be found in that area of memory. 2) What is a pointer? its the address component of a variable! its the part of a variable where the address is memory is actually stored. 3) You cannot directly set a pointer to a specific address, because many different things are happening on your computer and each of them is using memory. Therefore, the operating system makes sure you use memory that it has allocated to your job. If you think about these things, it may become clear why pointers are useful. Its useful to be able to tell other programs in your job where data resides, so it can access or even change that data. And thats why pointers are so useful in this situation. The QUSLMBR API and the QUSCRTUS API are both different programs. How do you access the same data that they populated, without doing many calls back and forth? Either by getting a pointer to their data, or by sending them a pointer telling them where to put the result! Its actually pretty simple, when you think of it that way... > > Once I did, I've been trying to clean it > up and make it more usable. Actually, I need to use the MBRL0200 > format, and so > I modified the code to handle that as well. However, I'm stuck on h > to define > the subfields for this format directly. In IBM's example, format > MBRL0100 was > used, which defines just the member name. MbrARR, as defined below, > is the > source for which the MBRL0x00 information is retrieved. If I tried > change > this to a data structure, I got errors. So I ended up using "Eval > MbrARRds = > MbrARR(index)" where MbrARRds is a data structure in which the > MBRL0200 > subfields are defined; not very elegant. (I probably missed somethi > really > simple here, so feel free to point it out.) > > d MbrARR s 100 Based(MbrPtr) Dim(32767) > d MbrARRds ds 100 > d MBName 1 10 > d MBSeu2 11 20 > d MBCreateDtTm 21 33 > d MBCCen 21 21s 0 > d MBCDat 22 27s 0 > d MBCTim 28 33s 0 > d MBChangeDtTm 34 46 > d MBUpdC 34 34s 0 > d MBUpdD 35 40s 0 > d MBUpdT 41 46s 0 > d MBMTxt 47 96 I'd do it more like this: d MbrPtr s * d MbrARRds ds based(MbrPtr) d MBName 1 10 d MBSeu2 11 20 d MBCreateDtTm 21 33 d MBCCen 21 21s 0 d MBCDat 22 27s 0 d MBCTim 28 33s 0 d MBChangeDtTm 34 46 d MBUpdC 34 34s 0 d MBUpdD 35 40s 0 d MBUpdT 41 46s 0 d MBMTxt 47 96 If you do this, with the example code that I send in th last message, you could simply change the line that says: p_MbrName = OffsetPtr(p_LH: Offset) to say: MbrPtr = OffsetPtr(p_LH: Offset) and, of course, change the call to QUSLMBR to use MBRL0200 instead of MBRL0100... and that SHOULD be all you'd have to change. What will, effectively, happen when you do this is that you'll be placing the MbrARRds structure above into the area of memory that the QUSLMBR API placed the data in. Therefore, PRESTO, you've got your data structure populated. In my opinion this is a much more elegant solution. In your example, you are, (apparently) assuming that each entry returned by QUSLMBR will always be 100 bytes long, and that you'll never have more than 32k of them. My method does not make these assumptions. :) The reason IBM's books teach you to use those big nasty arrays is because you can't do pointer arithmetic in the older versions of RPG (such as mine!) So how do you tell the system that you want a pointer to move to a certain offset? Someone came up with the idea of putting a big array over the area, and then using the address of each element in the array as a way of moving the pointer. In your release (V4R2) however, you don't need to mess with the big array thing, you can do direct pointer manipulation, as I explained in my last post. (I hope this is all making sense, I'm starting to feel like I'm babbling) > > Also, I've never used your technique for the prototyped program call > The ILE > RPG reference says that these are dynamic calls. Isn't there a > performance hit > for that (vs. static calls, i.e. CALL 'QUSCRTUS' ParmList)? IBM > doesn't let on > why, but the ILE RPG reference also states "The recommended way to > call a > program or procedure (written in any language) is to code a prototyp > call." > The ILE RPG Programmer's Guide states, "You can also write ILE > applications that > can interrelate with faster static calls. Static calls involve calls > between > procedures. A procedure is a self-contained set of code that perfor > a task > and then returns to the caller. An ILE RPG module consists of an > optional main > procedure followed by zero or more subprocedures. Because the > procedure names > are resolved at bind time (that is, when you create the program), > static calls > are faster than dynamic calls." Does this imply that called program > objects > must always be dynamically called, no matter the method used to code > the call? > This is not how I remember it from the RPG-III CALL op code. I thin > I've got > some reading to do. > > - Dan Bale Interesting. Unfortunately, regardless of whether you use the CALL op-code, or whether you use a prototype with EXTPGM keyword, they're still BOTH dynamic calls! Anytime you're calling an object thats a *PGM, its a "dynamic" call. It has to find the program in your library list, start a new call level (and sometimes even new activation group!) and so forth. This is what a dynamic call is.. A "static" call would be calling a procedure thats bound to your program. Thats very different from calling another program! Its more akin to calling a subroutine. The difference, of course, is that a static call can be to a subprocedure outside of your program, either in another module (a module thats bound at compile-time) or a service program (which is also bound at compile time, but is still kept in a different object elsewhere on disk) Since your calls are to QUSCRTUS, QUSLMBR, etc, they are all dynamic calls. Doesn't matter if you use a prototype or not. Some APIs (notably the CEExxx APIs or the Unix-type APIs, such as sockets or IFS access APIs) are "bindable". (This basically means that IBM put them in a service program.) However, the QUSxxx APIs are not bindable. In fact, they're still accessible from OPM programs. Whether you prototype the call and use callp or whether you use the CALL op-code, they're exactly the same! If they WERE bindable, how much difference would it make? Not much. You're doing, what, 3 calls? One to create the user space, one to list the members, and one to get a pointer? The total time that you'd save by static calls here is probably under a tenth of a second. The main part that needs to be fast is the part that you're doing in a loop. The part that can be done, potentially, thousands of times. and THAT part is using direct pointer access to the user space, not making calls at all! Heh... okay, I've been long-winded enough :) Now let me know if any of this made sense :) Scott Klement Information Systems Manager Klement's Sausage Co, Inc * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This is the RPG/400 Discussion Mailing List! To submit a new * * message, send your mail to "RPG400-L@midrange.com". To unsubscribe * * from this list send email to MAJORDOMO@midrange.com and specify * * 'unsubscribe RPG400-L' in the body of your message. Questions should * * be directed to the list owner / operator: david@midrange.com * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
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.