Ptr and ForeignPtr Questions

Ashley Yakeley ashley@semantic.org
Thu, 20 Sep 2001 02:31:56 -0700


At 2001-09-19 23:45, Manuel M. T. Chakravarty wrote:

>> What if the type is polymorphic (e.g. 
>> declared as 'Storable a => Ptr a' rather than something like 'Ptr Word8')?
>
>Also possible, as the argument to `Ptr' is just dummy.

What? What about 'withObject'? A Haskell 'Ptr a' is a C array-pointer of 
whatever corresponds to 'a'. I don't think the argument is dummy.

Consider this:

     int foo (char selector,char* arg)
          {
          if (selector == 100)
               return reinterpret_cast<unsigned char*>(arg)[1];
          if (selector == 200)
               return reinterpret_cast<unsigned short*>(arg)[1];
          return 0;
          }

     foreign import "foo" foo :: Storable a => Word8 -> Ptr a -> IO Int32;
     
     a <- withObject ([1,2] :: [Word8]) (foo 100);
     b <- withObject ([3,4] :: [Word16]) (foo 200);

Will this work as expected? I expect 'a' to be 2 and 'b' to be 4...

>> 3. What about ForeignPtr? Can instances of 'Storable a => ForeignPtr a' 
>> be used in FFI?
>
>They can be passed to C, but you can't get them back.  (The
>storange manager wouldn't know what finaliser to attach.)

OK. Are ForeignPtrs intelligible in the C function as pointers to the 
named type?

>> 4. Does newForeignPtr work safely with null pointers, and will the 
>> finalizer get called? For instance:
>> 
>>      fp <- newForeignPtr nullPtr finalFunc;
>>      let {isNull = (foreignPtrToPtr fp) == nullPtr};
>>      r <- withForeign fp (\p -> foo p);
>> 
>> Will foo be passed nullPtr? Will finalFunc ever get called? Is my use, 
>> above, of foreignPtrToPtr safe, and will isNull be True?
>
>Should work.  From the storage managers point of view, a
>`Ptr' is just an uninterpreted bit-pattern.  A glorified
>`Int'. 

So you are saying that the ForeignPtr code is not interested in the 
"pointer-ness" of the Ptr contents of a ForeignPtr, except when a 
ForeignPtr is used as an FFI argument?

Presumably this also means that one can create two separate ForeignPtrs 
around the same Ptr, each with their own finaliser set. Presumably they 
would not be equal (note that Eq (ForeignPtr a)). Is this correct?

Also, I assume that a ForeignPtr is eligible for garbage collection 
whenever it is no longer 'reachable', even if the Ptr it contains is 
reachable. Is that correct?

Is there anything resembling Java's 'soft' and 'weak references'?

> Of course, you should better make sure that
>`finalFunc' can handle getting a `nullPtr'.

Of course...

-- 
Ashley Yakeley, Seattle WA