Charles Mills wrote:
Interesting concept: wrap the assembler routines in a C++ class with an
initiator that allocates the storage. All "public" access to the assembler
functions through a C++ method wrapper.
So a public C++ method might be int assemblerfunc(int functionalparm1, char
*functionalparm2);
In turn it would simply call extern "OS" int ASSEMFUN(void *workarea24, int
functionalparm2, char *functionalparm2);
Exactly. Write you assembler routines to take a function code parameter
and have init/term functions which allocate/free resources.
Then you wrap your routine in a C++ classes to take advantage of type
safety and scoped contructors/destructors to implement the RAII idiom.
By using this technique you wont leak resources and should be exception
safe.
Very simple hacked example example:
extern "OS"
{
// assembler routine to do QSAM I/O
int ASMQSAM( int function, ... );
}
// QSAM I/O wrapper class
class QSAMFile
{
public:
// constructor
QSAMFile( const string& fileName )
{
// open the file
rc = ASMQSAM( FUNC_OPEN, &fp, fileName.c_str() );
}
// destructor
~QSAMFile()
{
// close the file
rc = ASMQSAM( FUNC_CLOSE, fp );
}
int read( char* buffer, size_t length )
{
rc = ASMQSAM( FUNC_READ, fp, buffer, length );
}
int write( const char* buffer, size_t length )
{
rc = ASMQSAM( FUNC_WRITE, fp, buffer, length );
}
private:
void * fp; // QSAM routine handle
};
Seems like an extra layer of complexity but it does solve the problems I
described.
An extra layer, but not really that much more complex. This is the basic
model I've used for years and it
works very well. It's also the same model that most GUI/Networking C++
APIs use, but they wrap the
legacy C API code instead of assembler.
Charles
-----Original Message-----
From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf
Of David Crayford
Sent: Sunday, February 21, 2010 7:54 PM
To: IBM-MAIN@bama.ua.edu
Subject: Re: Best practice for 24-bit storage in assembler called from C/C++
I would write the routines with init/term (Constructors/Destructors)
functions that allocate and free resources. Have the
init return a handle that you pass to the process/term functions,
usually just an address of a control block. Think of stdio
fopen(), fclose(), fread() etc socket functions etc that use handles.
Charles Mills 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.)
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.
Is there a better way? Is there some sort of "anchor word" where a library
of called assembler routines could save an address across calls? Is this
what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to
the
CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized
to
zero? Where is this stuff documented? I don't see much in LE Programming,
in
LE ILC, or in the C/C++ Programming Guide.
Is there some "LE-supported" solution to the whole problem, such as a
"below
the line stack" feature that an individual function (but not the whole
application!) could utilize?
Thanks,
Charles Mills
----------------------------------------------------------------------
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
----------------------------------------------------------------------
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
----------------------------------------------------------------------
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
----------------------------------------------------------------------
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