Article 152277 of comp.os.vms:
>My idea is to be able to write a class (portReader) which would be 
>initialized as portReader("TXA0:");  This class would be able to read 
>data received on the corresponding TTY port.  I also want to instansiate 
>more than one instance of this class; one for each port.
>
>Are there any suggestions on how can I keep Object Oriented on the VMS 
>when it comes to AST's.
>

Use static member functions as your AST routines. Pass the "this" pointer as 
the ASTPRM. Have the static functions call the "real" ASTs through the passed 
ASTPRM.

I don't know why you thought you needed to make things global...
>class portReader
>{
>public:
>  portReader (char *portName);
>  ~portReader ();
>private:
    static void TTYhangupHandler (portReader *);
    static void portReaderAST (portReader *);
    void HangupHandler(void);
    void AST(void);
>  void portReaderASTstarter (void);
>  void EndSession (void);
>  void ExitHandler (void);
>  void stringHandler (void);
>
>  struct dsc$descriptor TTYportNameDSC;
>  char    *TTYbuffer,*lineStr;
>  int lineStrPointer;
>  unsigned short  TTYchannel,TTY_QIOiosb[4];
>  long unsigned   ReadTerminatorMask[2],ExitConditionValue;
>};

>  struct {
>        unsigned long   flink;
>        void            (portReader::*exit_handler)();
>        unsigned long   arg_count;
>        unsigned long   *exit_status;
>  } ExitHandlerBlock;
>
>  struct io_status_block {   /*   I/O status block */
>         short int condition;
>         short int count;
>         int dev;
>         } iosb;
>
>
>portReader::portReader (char *portName)
>{
>  unsigned long status;
>
>  $DESCRIPTOR (TTYportNameDSC, portName);

Excuse me, but doesn't this declare an automatic variable with the same name 
as your data member? I don't think you're doing what you think you are.
>

..

>  if (!((status = sys$qiow (
>      0,
>      TTYchannel,
>      IO$_SETMODE | IO$M_CTRLYAST,
>      &TTY_QIOiosb, 0, 0,
>      &portReader::TTYhangupHandler,
>      this, 0, 0, 0, 0)) & 1))
>    lib$signal (status);
>
>  portReaderASTstarter ();
>}
>

void portReader::portReaderASTstarter (void)
>{
>  unsigned long status;
>
>  if (!((status = sys$qio (
>      0,
>      TTYchannel,
>      IO$_READVBLK | IO$M_NOECHO,
>      &TTY_QIOiosb,
>      &portReader::portReaderAST, this,
Note: pass "this" as ASTPRM.

>      TTYbuffer,
>      1, 0, &ReadTerminatorMask, 0, 0)) & 1))
>    lib$signal (status);
>
>  status = sys$alloc (&TTYportNameDSC, 0, 0, 0, 0);
>}
>
>void    portReader::portReaderAST (portReader *p)
>{
    p->AST(); // Note: call through the pointer
}

void portReader::AST(void)
{
>  unsigned long status;
>  int i;
>
>  if (TTY_QIOiosb[0] == SS$_HANGUP)
>    EndSession ();
>
>  if (!(TTY_QIOiosb[0] & 1 ))
>    sys$exit (TTY_QIOiosb[0]);
>
>  if (!((status = sys$qiow (
>      0,
>      TTYchannel,
>      IO$_READVBLK | IO$M_TIMED | IO$M_NOECHO,
>      &TTY_QIOiosb, 0, 0,
>      TTYbuffer + 1,
>      TTY_MAXBUF, 0,
>      &ReadTerminatorMask, 0, 0)) & 1))
>    lib$signal (status);
>
>  if (!(TTY_QIOiosb[0] & 1) && (TTY_QIOiosb[0] != SS$_TIMEOUT))
>    lib$signal (TTY_QIOiosb[0]);
>
>  for (i = 0;i <= TTY_QIOiosb[1];i++)
>  {
>    lineStr[lineStrPointer++] = TTYbuffer[i];
>    if (TTYbuffer[i] == '\n' || TTYbuffer[i] == '\r' || TTYbuffer[i] == 
>'\0')
>    {
>      lineStr[lineStrPointer] = '\0';
>      stringHandler ();
>      lineStrPointer = 0;
>    }
>  }
>  if(!go_out)
>    if (!((status = sys$qio (
>        0,
>        TTYchannel,
>        IO$_READVBLK | IO$M_NOECHO,
>        &TTY_QIOiosb,
>        &portReader::portReaderAST, this,
>        TTYbuffer,
>        1, 0, &ReadTerminatorMask, 0, 0)) & 1))
>      lib$signal (status);
>  return;
>}
>
>void portReader::TTYhangupHandler (portReader *p)
>{
    p->HangupHandler()
}

void portReader::HangupHandler(void)
{
>  EndSession();
>  return;
>}
>


