Ah but it's one *external* routine, not one pop routine. Or at least, if it
was a pop routine, it could only be written by solving David's original
query anyway...
David: how dirty do you want to be? You can get the address of any pop
object using fast_subscrintvec on a full field. So something like this
should work:
vars x=initintvec(100);
vars temp = initv(x);
vars x_addr = fast_subscrintvec(1,temp); ;;; address of x as a (pop)
integer
exacc foo(x_addr+30*sizeof(:int), 10);
can't recall whether I got sizeof right. Also you need to declare foo in pop
as taking an int, so that pop converts the value back from a pop int to a
machine int. And finally, if a gc happens between the last two steps you're
scuppered, unless you declare your intvec structure to be fixed (using
consfixed, but I forget the syntax).
Roger
Jonathan L Cunningham wrote:
> On Mon, 21 Apr 2003 16:20:53 +0000 (UTC), davidy@cogs.susx.ac.uk
> wrote:
>
> >Can anyone offer any suggestions as to how to persuade the external
> >interface to pass the address of an arbitrary element of a vector to an
> >external procedure?
> >
>
> (snip)
>
> >I realise that I can always provide an intermediate external routine
> >that takes an address and an offset and adds them before calling the
> >real routine. However, that's a pain as it has to be done for every
> >external routine I want to call, and it would be much handier to have
> >something that did it in Pop-11.
>
> Surely only one intermediate? (Or one for each type of external
> pointer).
>
> The new routine doesn't call the real routine: it merely returns
> the address for you to pass to the real routine?
>
> I.e. instead of
>
> vars x = initintvec(100);
> exacc foo(x[30], 10);
>
> which doesn't work, you do
>
> vars x = initintvec(100);
> exacc foo(addr(x, 30), 10);
>
> where you have to define the addr function (once) but can use it
> wherever you want to do this.
>
> Am I missing something?
>
> Jonathan
>
> --
> (Replace netspam by jlc when appropriate)
|