Re: pointer to derived type var?
Ancient_Hacker wrote:
> Ah, good , this worked, first time:
>
> subroutine IntToPointer( IncomingAddress )
> common/ptr/ThePointer
> integer * 4 ThePointer, IncomingAddress
> ThePointer = IncomingAddress !! Stuff address into integer, will be
> picked up as ptr
> return
> end
>
>
> subroutine Timing_Show
> include 'Timing.Defs'
> common/ptr/ThePointer !! integer where stuffed, but here as a
> pointer to Timing_Rec
> type(Timing_Rec) :: times
> type(Timing_Rec), pointer :: ThePointer
>
> ----------------------------------------------
>
> I could ahve done it all even simpler by EQUIVALENCEing the integer and
> pointer variables.
>
But, you cannot equivalence derived types.
This sort of hack can be done more cleanly, and is fairly reliable under
the assumption that a Fortran pointer-to-scalar is really just a single
raw memory address. That is not guaranteed, but it appears to be fairly
reliable.
Of course, the Cray Pointer extension is better than an unsupported
hack, but here's some tips if you go the hack route.
1) If you do implement a hack, you should implement a test subroutine at
start-up, to determine if the hack seems to work OK. But, you can never
be 100% certain.
2) Avoid using integer-sized pointers. Instead, use a derived-type
containing a scalar pointer as a sort of void-pointer.
3) There is no casting in Fortran, just molding. If this pointer hack
works, the best tool is TRANSFER() which 'molds' the data. Casting
allows you to lie about a pointer's target. Molding only claims the raw
binary data is copied. So, you mold data like this:
-------------------
type void_ptr
sequence; private
integer, pointer :: void
end type void_ptr
type real_ptr
sequence; private
real, pointer :: value
end type void_ptr
type(real_ptr) :: r
type(void_ptr) :: v
r = transfer(v,r)
-------------------
If, for some reason, you have to go from a C-pointer size integer,
TRANSFER will also work:
type(real_ptr) :: r = transfer(v,int_var)
One advantage of transfer over a common block is that common block names
pollute the global name space. With derived types banned from
EQUIVALENCE, TRANSFER() is the primary hacking tool. And, it is cleaner
because you do not look at the same memory as being two different types
at the same time.
Joe
|