
On 21 October 2005 14:40, Joel Reymont wrote:
I stumbled upon this when binding the Zlib library and want to make sure I'm doing this right.
foreign import ccall unsafe "uncompress" uncompress_ :: Ptr Word8 -> Ptr CULong -> Ptr Word8 -> CULong -> IO CInt
You give this function the address of your size as second argument and it updates size for you. basic uncompress(char* buf, unsigned long *size, ...) for you.
Is it correct that I need to allocate a chunk of 4 bytes to be passed into C and updated there and then need to peek my value from that chunk of memory?
yes, something like with $ \pculong -> r <- uncompress_ buf pculong ... size <- peek pculong
I thought StablePtr would give me the address of a Haskell value but it gives me an offset into some table instead.
That's right, the reason being that Haskell values move around when GC happens. Cheers, Simon

Is there a particular reason why StablePtr cannot provide a "fixed" memory address? Then 4 bytes of memory won't need to be allocated so that C could write to them and C could just modify the Haskell variable. On Oct 21, 2005, at 3:17 PM, Simon Marlow wrote:
yes, something like
with $ \pculong -> r <- uncompress_ buf pculong ... size <- peek pculong
I thought StablePtr would give me the address of a Haskell value but it gives me an offset into some table instead.
That's right, the reason being that Haskell values move around when GC happens.

On Fri, Oct 21, 2005 at 03:19:36PM +0100, Joel Reymont wrote:
Is there a particular reason why StablePtr cannot provide a "fixed" memory address? Then 4 bytes of memory won't need to be allocated so that C could write to them and C could just modify the Haskell variable.
because haskell values don't have the same representation as C values. haskell values are pointers to updatable thunks. in any case 'with' just allocates 4 bytes on the stack (the same as a auto C declaration) so is quite speedy compared to what it would take to make a haskell value look like a C one. not to mention haskell values can't be modified. John -- John Meacham - ⑆repetae.net⑆john⑈

Am Samstag, 22. Oktober 2005 01:42 schrieb John Meacham:
On Fri, Oct 21, 2005 at 03:19:36PM +0100, Joel Reymont wrote:
Is there a particular reason why StablePtr cannot provide a "fixed" memory address? Then 4 bytes of memory won't need to be allocated so that C could write to them and C could just modify the Haskell variable.
because haskell values don't have the same representation as C values. haskell values are pointers to updatable thunks. in any case 'with' just allocates 4 bytes on the stack (the same as a auto C declaration) so is quite speedy compared to what it would take to make a haskell value look like a C one. not to mention haskell values can't be modified.
2 tiny remarks: * In Simon's example the first parameter to 'with' (the initial buffer size) was missing, but I guess you've figured this out already. In general: If the pointer you're passing to C has "in" semantics, 'with' (or one of its variations) is your friend. For "in/out" semantics, use 'with' + 'peek', and for "out" semantics" use 'alloca' + 'peek'. * As already mentioned, StablePtr can even refer to something which has no direct C counterpart, like Haskell functions. Needing them in the C world seems strange at first, because there is nothing thrilling you can do with them but pass them back to Haskell. But there are actually some good uses for that, like interfacing to callback-based C APIs where some additional bookkeeping is needed. Cheers, S.

Is "with" better than allocaBytes? On Oct 22, 2005, at 12:42 AM, John Meacham wrote:
because haskell values don't have the same representation as C values. haskell values are pointers to updatable thunks. in any case 'with' just allocates 4 bytes on the stack (the same as a auto C declaration) so is quite speedy compared to what it would take to make a haskell value look like a C one. not to mention haskell values can't be modified.

Am Montag, 24. Oktober 2005 17:20 schrieb Joel Reymont:
Is "with" better than allocaBytes?
"with" is just a utility function around "alloca" and "poke", where "alloca" is another utility function around "allocaBytes". Here the code from the repository: with val f = alloca $ \ptr -> do poke ptr val res <- f ptr return res (Hmmm, why not simplify the last two lines to just "f ptr"?) GHC does some tricky things you probably don't want to know about :-) to do something better for "alloca" than an exception-protected "malloc"/"free" pair. In a nutshell: "with" is not better than "allocaBytes", it is something different. "with" can be used to pass a Storable Haskell value in a temporary memory buffer to a function, while "allocaBytes" only does plain temporary memory allocation. Cheers, S.

So both with and allocaBytes allocate bytes on the stack then, correct? On Oct 29, 2005, at 1:13 PM, Sven Panne wrote:
In a nutshell: "with" is not better than "allocaBytes", it is something different. "with" can be used to pass a Storable Haskell value in a temporary memory buffer to a function, while "allocaBytes" only does plain temporary memory allocation.

Am Samstag, 29. Oktober 2005 14:27 schrieb Joel Reymont:
So both with and allocaBytes allocate bytes on the stack then, correct?
It depends on what you mean by "stack". :-) From a conceptual point of view, both pass a pointer to a temporary memory region to a given action *which is only valid during the execution of the action*, so it would be incorrect to if the pointer somehow "escapes" the action. How this temporary memory is actually allocated depends on the implementation: Hugs and NHC use malloc/free, ensuring that free is even called in case of an exception, so that there will be no space leaks. GHC does something more efficient by allocating the memory from the normal Haskell runtime heap, but ensuring that the memory is never moved by garbage collection. This is called "pinned memory" sometimes, see e.g. Java's JNI. Cheers, S.
participants (4)
-
Joel Reymont
-
John Meacham
-
Simon Marlow
-
Sven Panne