[David said]
> I am trying to externally load a function, tcgetattr actually.
> The type for this is:
>
> int tcgetattr(int, struct termios *);
>
> How should I accomplish this in pop11 ?
>
> So far I have set up a p_typespec for the termios struct.
> But cannot seem to easily specify that I want a ptr to that struct as
> the second argument.
>
"And verily it was said, many and wonderful are the ways of accessing
the world external in Pop-11"... and here are a few of them:
Ok. We have your p_typespec for the -termios- structure
p_typespec termios {
c_iflag :long,
c_oflag :long,
c_lflag :long,
c_cc :byte[19]
};
or whatever.
From Poplog V14.5 you can use the "exptr_mem" external pointer class
(see REF * EXTERNAL_DATA) so:
vars t_ptr = initexptr_mem(SIZEOFTYPE(:termios))
which can be stated more succinctly with the -EXPTRINITSTR- macro (see
REF * DEFSTRUCT)
vars t_ptr = EXPTRINITSTR(:termios);
These just create pointers to a fixed-address chunk of memory of the
specified size. You can use optional arguments to specify whether the
memory should be garbage collected just like you can with -cons_fixed-.
Alternatively, you can just pass any Poplog vector class wrapped up as an
external pointer --- as long as you're willing to be careful with GC:-)
vars t_ptr =
exptr_init_fixed(SIZEOFTYPE(:termios, :int), intvec_key);
You can pass optional arguments to create fixed-address structures if
necessary (before "exptr_mem" structures, -EXPTRINITSTR- used to work
like this.)
In either of these case you would do something like this:
exload 'tcgetattr'
(language C)
raw_tcgetattr(int, termios) :int <- tcgetattr;
endexload;
vars err=exacc raw_tcgetattr(poprawdevout.device_os_channel, t_ptr);
err=>
** 0
exacc :termios t_ptr.c_iflag=>
** 11526
If you would like to access the pointer like a Pop-11 structure you can
use LIB * SHADOWCLASS. This allows you to create a Pop-11 "shadow" of an
external structure. For example, the following
uses shadowclass;
shadowclass termiosP :termios;
will create the following procedures
istermiosP(item) -> bool
inittermiosP() -> termiosP
constermiosP(iflag, oflag, lflag, cc) -> termiosP
desttermiosP(termiosP) -> (iflag, oflag, lflag, cc)
filltermiosP(iflag, oflag, lflag, cc, termiosP) -> termiosP
which have there normal Pop-11 meanings. It will also create the
following field access procedures
c_iflag(termiosP) -> long
c_oflag(termiosP) -> long
c_lflag(termiosP) -> long
c_cc(termiosP) -> vec
along with two special procedures;
importtermiosP(exptr) -> termiosP
Which will take an external pointer to a termios structure, and
return the shadowclass equivalent.
refreshtermiosP(termiosP) -> termiosP
Which refreshes the Pop-11 shadow of the external structure.
It also creates the special "shadow key" structure
termiosP_shadowkey
Despite all this, it's dead easy to use:
define tcgetattr(dev, termiosP) -> int;
lvars dev, termiosP, int;
exacc raw_tcgetattr(dev.device_os_channel, termiosP) -> int;
;;; EXTERNAL STRUCTURE CHANGED SO WE NEED TO REFRESH SHADOW
refreshtermiosP(termiosP) ->;
enddefine;
vars t_ptr=inittermiosP();
t_ptr=>
** <termiosP 0 0 0 {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}>
tcgetattr(poprawdevout, t_ptr)=>
** 0
t_ptr=>
** <termiosP 11526 5 189 {0 0 138 59 3 28 127 21 4 0 0 0 17 19 26 25 18 15 23}>
t_ptr.c_iflag=>
** 11526
Obviously, the ease of use has efficiency drawbacks (that Pop-11 shadow
takes time and space to maintain.) For full details see REF *
SHADOWCLASS.
Hope this makes some sense :-)
aids (adrianh@cogs.susx.ac.uk) ObDisclamer: Poplog used to pay my wages
Phone: +44 (0)273 678367 URL: http://www.cogs.susx.ac.uk/users/adrianh/
|