Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-13 Thread Donn Cave
Quoth =?ISO-8859-1?Q?Yves_Par=E8s?= yves.pa...@gmail.com,

 You mean I have to use a type like StablePtr (IORef Stuff)?
 Because there I can only peek (deRefStablePtr) the pointer, not poke it.

 I take it I should return to C a StablePtr to the new value if I don't want
 to use IORefs...

Yes ...

 Or else I have to use regular Ptrs with Foreign.Marshall.Alloc.malloc

yes!

Both of these are good ways, to do different things.  In your initial
message, you asked about a foreign function modifying a value in storage
accessible from Haskell - that's regular Ptr.  Either way, read or write,
communication with the foreign layer is through Ptr, not StablePtr.

StablePtr is for Haskell expressions, which would be totally inscrutable
to the foreign function anyway, and which naturally do not expect to
be modified, so yes, a new value shall be attached to a new StablePtr.

Donn

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Yves Parès
Hello,

According to the documentation (
http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html),
StablePtrs aims at being opaque on C-side.
But they provide functions to be casted to/from regular *void**'s.
Does that mean if for instance you have a StablePtr CInt you can cast it to Ptr
() and alter it on C-side?

void alter(void* data)
{
int* x = (int*)data;
*x = 42;
}

--

-- using 'unsafe' doesn't change anything.
foreign import ccall safe alter
alter :: Ptr () - IO ()

main = do
sptr - newStablePtr (0 :: CInt)
deRefStablePtr sptr = print
alter (castStablePtrToPtr sptr)  -- SEGFAULTS!
deRefStablePtr sptr = print
freeStablePtr sptr


But I tried it, and it doesn't work: I got a segfault when 'alter' is
called.

Is it normal? Does this mean I can only use my pointer as opaque? (Which I
know to be working, as I already got a C function call back into Haskell
and pass it the StablePtr via a 'foreign export')
But in that case, what is the use of castStablePtrToPtr/castPtrToStablePtr,
as you can already pass StablePtrs to and from C code?

Thanks!
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Antoine Latter
On Sun, Feb 12, 2012 at 8:18 AM, Yves Parès yves.pa...@gmail.com wrote:
 Hello,

 According to the documentation
 (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html),
 StablePtrs aims at being opaque on C-side.
 But they provide functions to be casted to/from regular void*'s.
 Does that mean if for instance you have a StablePtr CInt you can cast it to
 Ptr () and alter it on C-side?

 void alter(void* data)
 {
     int* x = (int*)data;
     *x = 42;
 }

 --

 -- using 'unsafe' doesn't change anything.
 foreign import ccall safe alter
     alter :: Ptr () - IO ()

 main = do
     sptr - newStablePtr (0 :: CInt)
     deRefStablePtr sptr = print
     alter (castStablePtrToPtr sptr)  -- SEGFAULTS!
     deRefStablePtr sptr = print
     freeStablePtr sptr


 But I tried it, and it doesn't work: I got a segfault when 'alter' is
 called.


I think that 'castStablePtrToPtr' exists because many C APIs use
'void*' to mean 'opaque lump of data', and these exist to conform to
that sort of API.

Antoine

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Albert Y. C. Lai

On 12-02-12 09:18 AM, Yves Parès wrote:

According to the documentation
(http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html),
StablePtrs aims at being opaque on C-side.


The doc multiply warns again and again that StablePtr, as well as 
whatever Ptr you get from castStablePtrToPtr, are opague (meaningless) 
to the C side. This is sanctioned by Haskell 2010, and GHC certainly 
exploits it to the fullest. The following example shows what kind of 
pointer values the C side receives for real (I deliberately do not 
free anything to show you more possible values):


#include stdio.h
void expose(void *p, void *q)
{
  printf(%p %p\n, p, q);
}

import Foreign.StablePtr
import Foreign.Ptr
main = do
  printout (0 :: Int)
  printout (let x = not x in x)
  printout ([] :: [Integer])
printout :: a - IO ()
printout thunk = do
  p - newStablePtr thunk
  expose p (castStablePtrToPtr p)
  -- I deliberately do not free
foreign import ccall expose :: StablePtr a - Ptr b - IO ()

Typically the output is like
0xf 0xf
0x10 0x10
0x11 0x11
Looks more like keys of a lookup table than pointers.

I do not know what good is castStablePtrToPtr for, given that StablePtr 
is already translated to C side void*, so that no intermediate Ptr step 
is necessary. Perhaps there is a story from a historical perspective.



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Yves Parès
Yes, but from C side, a StablePtr* is **already a **void**. (See HsFFI.h
which typedefs HsStablePtr to void*)
So its sufficient for a use as an opaque pointer, no need to cast it.

So what is the use of casting it to a Ptr () if this doesn't allow to
access the memory space addressed?


2012/2/12 Antoine Latter aslat...@gmail.com

 On Sun, Feb 12, 2012 at 8:18 AM, Yves Parès yves.pa...@gmail.com wrote:
  Hello,
 
  According to the documentation
  (
 http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html
 ),
  StablePtrs aims at being opaque on C-side.
  But they provide functions to be casted to/from regular void*'s.
  Does that mean if for instance you have a StablePtr CInt you can cast it
 to
  Ptr () and alter it on C-side?
 
  void alter(void* data)
  {
  int* x = (int*)data;
  *x = 42;
  }
 
  --
 
  -- using 'unsafe' doesn't change anything.
  foreign import ccall safe alter
  alter :: Ptr () - IO ()
 
  main = do
  sptr - newStablePtr (0 :: CInt)
  deRefStablePtr sptr = print
  alter (castStablePtrToPtr sptr)  -- SEGFAULTS!
  deRefStablePtr sptr = print
  freeStablePtr sptr
 
 
  But I tried it, and it doesn't work: I got a segfault when 'alter' is
  called.
 

 I think that 'castStablePtrToPtr' exists because many C APIs use
 'void*' to mean 'opaque lump of data', and these exist to conform to
 that sort of API.

 Antoine

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Yves Parès
Thanks for your explanation Albert, it makes things clearer.

So StablePtrs are just useful so that C code can:
1) call back into Haskell (through a foreign exported function like
doSomethingWithTheObjectIGaveYou
:: StablePtr MyObjectType - Stuff - IO ())
2) store them to return them later to Haskell when prompted (through a
foreign imported function like getObject :: Stuff - IO (StablePtr
MyObjectType))
That's it?

But then,
In use case 1), how can a Haskell function modify the data addressed?

If StablePtrs cannot have their pointed value modified (either C or
Haskell-side), that mostly limits their interest, doesn't it?


2012/2/12 Albert Y. C. Lai tre...@vex.net

 On 12-02-12 09:18 AM, Yves Parès wrote:

 According to the documentation
 (http://hackage.haskell.org/**packages/archive/base/4.5.0.0/**
 doc/html/Foreign-StablePtr.**htmlhttp://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html
 ),
 StablePtrs aims at being opaque on C-side.


 The doc multiply warns again and again that StablePtr, as well as whatever
 Ptr you get from castStablePtrToPtr, are opague (meaningless) to the C
 side. This is sanctioned by Haskell 2010, and GHC certainly exploits it to
 the fullest. The following example shows what kind of pointer values the
 C side receives for real (I deliberately do not free anything to show you
 more possible values):

 #include stdio.h
 void expose(void *p, void *q)
 {
  printf(%p %p\n, p, q);
 }

 import Foreign.StablePtr
 import Foreign.Ptr
 main = do
  printout (0 :: Int)
  printout (let x = not x in x)
  printout ([] :: [Integer])
 printout :: a - IO ()
 printout thunk = do
  p - newStablePtr thunk
  expose p (castStablePtrToPtr p)
  -- I deliberately do not free
 foreign import ccall expose :: StablePtr a - Ptr b - IO ()

 Typically the output is like
 0xf 0xf
 0x10 0x10
 0x11 0x11
 Looks more like keys of a lookup table than pointers.

 I do not know what good is castStablePtrToPtr for, given that StablePtr is
 already translated to C side void*, so that no intermediate Ptr step is
 necessary. Perhaps there is a story from a historical perspective.


 __**_
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/**mailman/listinfo/haskell-cafehttp://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Antoine Latter
On Sun, Feb 12, 2012 at 3:09 PM, Yves Parès yves.pa...@gmail.com wrote:
 But then,
 In use case 1), how can a Haskell function modify the data addressed?


http://hackage.haskell.org/packages/archive/base/latest/doc/html/Foreign-StablePtr.html#v:deRefStablePtr

Antoine

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Donn Cave
Quoth Yves Pares,
...
 If StablePtrs cannot have their pointed value modified (either C or
 Haskell-side), that mostly limits their interest, doesn't it?

I'm not sure I follow what's happening in the two cases you mention,
but in case it helps, I use StablePtr as a way to smuggle Haskell
values through a non-Haskell layer.  On the other side, they are
just things - not really pointers, so while void* is all right as
long as it's the right size, it is a little misleading.  Tag might
be a better word.

castStablePtrToPtr doesn't change that - you still get a tag, not
a memory address.  I can think of no use for it, unless you want
to call a function that happens to use a Ptr () without expecting
it to point somewhere in the memory address sense.

Since they're Haskell values, it would be perverse to modify them.
I just want them back, in a Haskell function dispatched by the
other layer.  If I want to pass data per se to the other side,
I have to marshal it to be readable CInts and such, and then pass
it as a Ptr.  And/or if the data is to be modified by the other
side, same deal, I have to un-marshal it back into Haskell.

I actually use them with a C++ layer, where of course the dispatch
happens through C++ object member functions.  That allows me to
map Haskell functions to the C++ API in a C++ derived class that
just maintains a table of the actual Haskell `member functions',
and a StablePtr for the actual Haskell data.

Donn

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread John Meacham
No, you can do nothing with the pointer on the C side other than pass
it back into haskell. It may not even be a pointer, it may be an index
into an array deep within the RTS for instance. The reason they can be
cast to void *'s is so you can store them in C data structures that
don't know about haskell, which tend to take void *s.

John

On Sun, Feb 12, 2012 at 6:18 AM, Yves Parès yves.pa...@gmail.com wrote:
 Hello,

 According to the documentation
 (http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Foreign-StablePtr.html),
 StablePtrs aims at being opaque on C-side.
 But they provide functions to be casted to/from regular void*'s.
 Does that mean if for instance you have a StablePtr CInt you can cast it to
 Ptr () and alter it on C-side?

 void alter(void* data)
 {
     int* x = (int*)data;
     *x = 42;
 }

 --

 -- using 'unsafe' doesn't change anything.
 foreign import ccall safe alter
     alter :: Ptr () - IO ()

 main = do
     sptr - newStablePtr (0 :: CInt)
     deRefStablePtr sptr = print
     alter (castStablePtrToPtr sptr)  -- SEGFAULTS!
     deRefStablePtr sptr = print
     freeStablePtr sptr


 But I tried it, and it doesn't work: I got a segfault when 'alter' is
 called.

 Is it normal? Does this mean I can only use my pointer as opaque? (Which I
 know to be working, as I already got a C function call back into Haskell and
 pass it the StablePtr via a 'foreign export')
 But in that case, what is the use of castStablePtrToPtr/castPtrToStablePtr,
 as you can already pass StablePtrs to and from C code?

 Thanks!

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stable pointers: use of cast to/from Ptr

2012-02-12 Thread Yves Parès
You mean I have to use a type like StablePtr (IORef Stuff)?
Because there I can only peek (deRefStablePtr) the pointer, not poke it.

I take it I should return to C a StablePtr to the new value if I don't want
to use IORefs...

Or else I have to use regular Ptrs with Foreign.Marshall.Alloc.malloc

2012/2/12 Antoine Latter aslat...@gmail.com

 On Sun, Feb 12, 2012 at 3:09 PM, Yves Parès yves.pa...@gmail.com wrote:
  But then,
  In use case 1), how can a Haskell function modify the data addressed?
 


 http://hackage.haskell.org/packages/archive/base/latest/doc/html/Foreign-StablePtr.html#v:deRefStablePtr

 Antoine

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe