Thanks, Tony. Yes, the amount of processing varies but is more than atomic, I guess. It does not fit a model of open/get/get/get/close for which a "handle" is well-suited. There's not much relationship among the routines other than that they're all part of a single larger solution, they're all in assembler, and I wrote them all <g>.
I thought I had a pretty good solution and I just spent a frustrating afternoon coding it -- but I've hit a possibly fatal snag. I had this bright idea of coding a pointer in global storage in the C++ code and doing a __malloc24() into it, and then referencing it with EXTRN from the assembler, but the pre-linker is not resolving it. The fundamental problem I guess is that any solution that keeps a pointer around "somewhere in the code" is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included <stdlib.h>. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -----Original Message----- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Monday, February 22, 2010 5:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 21 February 2010 21:00, Charles Mills <charl...@mcn.org> wrote: > I'm writing a fairly large MVS batch application in C++. At several points > it is necessary to call "library" type routines that I am writing in > assembler. Several of the routines (unfortunately) need to use QSAM macros > and so need below-the-line storage. > > Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and > FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for > a routine that is called multiple times. (And it would not work at all if > the routine had to save state across calls, but fortunately that is not the > case, at least for my requirements so far.) It sounds as though you're doing a relatively large amount of processing on each call, i.e. you're not just reading a record and return it. So perhaps GETMAIN on the way in, and FREEMAIN upon exit wouldn't be too bad. > I could make the calling C++ responsible for providing a "work area" > obtained with _malloc24(). But I don't like that for "aesthetic" reasons - > violates encapsulation, making the caller responsible for the inner workings > of the called function. If your library routines are logically related, you could have an init call that returns a "handle" to the C++ routine, which would be responsible for maintaining it across calls. Then the handle is part of each subsequent call, including the final cleanup one. That sounds like an appropriate level of opacity/encapsulation. If you want to think of all this in terms of objects and constructors/destructors, well fine. The handle is really just the address of your BTL storage block, of course. ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html