DLM heap variable access [message #66984] |
Sat, 27 June 2009 12:34  |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
I got tired of waiting for the ITTVIS folks to implement some more
data structures in IDL. Coding a bunch of them (lists, maps, stacks)
in IDL would be a fair amount of rewriting the wheel, and also
inefficient, because of the way IDL' s pointers and scalars work. So I
decided that the nicest solution would be to have IDL objects as
wrappers to C++ containers. It is simple enough to do it writing a DLM
in the way Ronn Kling' s book suggests, with the IDL object containing
a (real) pointer to the C++ object, and wrapper methods to call the C+
+ methods.
However, I was unhappy with having to make a method in IDL that passes
the object pointer and the arguments to a C++ wrapper, that then does
the job with the C++ object. It would be much nicer to write the IDL
method directly in C++. The trouble is how to get access to the IDL
object's self from the C++ routine, to retrieve the C++ object pointer
in it. As Ronn mentions, the IDL object reference gets passed to the
method in argv[0], but nowehre I could find a reference to how to use
it, except for this very unsatisfying sentence
"Direct access to pointer and object reference heap variables (types
IDL_TYP_PTR and IDL_TYP._OBJREF, respectively) is not allowed."
from IDL' s documentation. I figured that the IDL object reference is
passed in argv[0] for some use, and it appears that some objects
written by ITTVIS do exactly that. So after some experimenting and
browsing through idl_export.h, I eventually figured out how to do it.
In the description below, the IDL object was defined with a single
structure member, self.obj, that is a pointer to a byte array where
the C++ pointer is stored (as suggested in Ronn's book).
1) argv[0] has a type IDL_TYP_OBJREF. Therefore, its value contains
the heap variable identifier (IDL_HVID hvid). Of course that is just
IDL' s id number for the heap variable, not an actual pointer.
2) idl_exports.h contains the prototype:
IDL_HEAP_VPTR IDL_CDECL IDL_HeapVarHashFind(IDL_HVID hash_id)
I found that this function returns a pointer to the heap variable
given its identifier.
3) What heap variable is pointed to by argv[0]->value.hvid? The IDL
object's self!
4) It is now necessary to retrieve the heap variable pointed to by
self.obj. This is done with IDL_HeapVarHashFind on the heap variable
id in self.obj:
//Get a pointer to self (self is {pp_stl,obj:ptr_new()}):
IDL_HEAP_VPTR ohvptr=IDL_HeapVarHashFind(argv[0]->value.hvid);
//Get the identifier of the heap variable of self.obj:
IDL_HVID *pind=(IDL_HVID *) ohvptr->var.value.arr->data;
//Get a pointer to *(self.obj):
IDL_HEAP_VPTR hvptr=IDL_HeapVarHashFind(*pind);
//Get the real pointer from *(self.obj):
memcpy(&object,hvptr->var.value.arr->data,sizeof(object));
|
|
|
Re: DLM heap variable access [message #67148 is a reply to message #66984] |
Mon, 06 July 2009 05:16   |
Jason Ferrara
Messages: 17 Registered: February 2008
|
Junior Member |
|
|
On Jun 27, 3:34 pm, pp <pp.pente...@gmail.com> wrote:
> I got tired of waiting for the ITTVIS folks to implement some more
> data structures in IDL. Coding a bunch of them (lists, maps, stacks)
> in IDL would be a fair amount of rewriting the wheel, and also
> inefficient, because of the way IDL' s pointers and scalars work. So I
> decided that the nicest solution would be to have IDL objects as
> wrappers to C++ containers. It is simple enough to do it writing a DLM
> in the way Ronn Kling' s book suggests, with the IDL object containing
> a (real) pointer to the C++ object, and wrapper methods to call the C+
> + methods.
With Slither you can use Python's container classes from IDL. I
realize its a bit extreme to use a method that requires a Python
install plus a Slither license just to get some containers, but it
does work rather well.
IDL> pb=pyimport("__builtin__")
% Loaded DLM: SLITHER.
IDL> l=pb->list()
IDL> l->append, 6
IDL> l->append, 3
IDL> l->append, 23
IDL> print, pb->len(l)
3
IDL> print, l->__getitem__(1)
3
IDL> print, l->__getitem__(0)
6
IDL> print, l->__getslice__(1,3)
3 23
IDL> print, pytoidl(l)
6 3 23
IDL> print, l->pop()
23
IDL> print, l->pop()
3
IDL>
IDL>
IDL>
IDL> d=pb->dict()
IDL> d->__setitem__, "something",2
IDL> d->__setitem__, "otherthing",3
IDL> d->__setitem__, "nothing",6
IDL> print, d->__getitem__("otherthing")
3
IDL> print, d->keys()
nothing otherthing something
IDL> print, d->values()
6 3 2
|
|
|
Re: DLM heap variable access [message #67153 is a reply to message #66984] |
Fri, 03 July 2009 08:46   |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
I was looking around the files, and found some odd things:
1) There is a method in list__define, which appears to do what the
documentation calls Join. But it is called Simp. However, it tries to
call a nonexisting function list_simp, which I thus I replaced by a
call to list_join.
2) 3 of the methods (function and procedure Show, plus Simp), when
called, apparently destroyed the list. That is:
IDL> a=obj_new('list')
IDL> a->append,9d0
IDL> a->append,5d0
IDL> print,list_active()
1
IDL> a->show
(9.0000000 5.0000000)
IDL> print,list_active()
0
IDL> obj_destroy,a
% LIST_FREE: Argument not of list type.
Which I found could be solved (though I do not understand why), by
replacing the argument in the calls to the list functions, to use a
copy of self.d. That is, replacing
print, list_show(self.d)
by
d=self.d
print, list_show(d)
|
|
|
|
|
|
Re: DLM heap variable access [message #67288 is a reply to message #66984] |
Mon, 13 July 2009 14:40  |
rtk
Messages: 22 Registered: September 2008
|
Junior Member |
|
|
On Jul 13, 10:05 am, rtk <oneelkr...@hotmail.com> wrote:
> The 32-bit versions should work on 64-bit machines.
Of course, this is only true of 32-bit applications, not DLMs :)
Anyway, I just built 64-bit Linux versions, email me if you want
them. I'll try to get them posted on the web site as well. 64-bit
Windows I'll get to later in the week.
Ron
rkneusel@ittvis.com
|
|
|
Re: DLM heap variable access [message #67292 is a reply to message #66984] |
Mon, 13 July 2009 09:05  |
rtk
Messages: 22 Registered: September 2008
|
Junior Member |
|
|
On Jul 11, 11:45 am, pp <pp.pente...@gmail.com> wrote:
> Of course the answer to this was obvious. I just keep forgetting that
> structure elements are passed by value, not by reference. Even though
> list_show() does not change the value of its argument, if it is given
> an identifier (to a non-empty list) by value, it erases the list.
Sorry, I missed following up on this thread. The list functions, and
the
higher-order functions, all destroy any list given as an argument if
that
list is not assigned to a variable already. This is necessary to
allow the
output of one function call to be immediately used by another without
wasting
memory all over the place.
It is entirely possible that I left list.sav out. The list object
calling
list_simp is probably left over from an earlier version. Personally,
I use
the bare list functions for speed, not the list object.
I'll look into building 64-bit versions of the DLMs but this week
seems like
it will be busy. The 32-bit versions should work on 64-bit machines.
Ron
|
|
|
Re: DLM heap variable access [message #67307 is a reply to message #67153] |
Sat, 11 July 2009 10:45  |
penteado
Messages: 866 Registered: February 2018
|
Senior Member Administrator |
|
|
> Which I found could be solved (though I do not understand why), by
> replacing the argument in the calls to the list functions, to use a
> copy of self.d. That is, replacing
>
> print, list_show(self.d)
>
> by
>
> d=self.d
> print, list_show(d)
Of course the answer to this was obvious. I just keep forgetting that
structure elements are passed by value, not by reference. Even though
list_show() does not change the value of its argument, if it is given
an identifier (to a non-empty list) by value, it erases the list.
|
|
|