First note: it's not GCC, but Haskell's GC.
Second, I believe it's not necessary to put strict annotations because all function parameters are evaluated before calling FFI function. It's just a general good practice to make all data fields strict unless there are reasons to do otherwise.
Thanks guys,I looks like there are basically 2 ways to do this:1) Build a structure of ForeignPtr with finalizers that will be freed whenever the GCC feels like it2) Nest allocations and the will free at the end of IOI noticed that in Real World Haskell the example of #1 has a ForeignPtr and ByteString in a data constructor, and both are bang noted as strict. Is this required before passing the data to a C-call to ensure it is evaluated or just a choice with the usual implications, such that with or without the evaluation of the C-call is well behaved?Mike
Sent from my iPad_______________________________________________> data Person = Person String String IntWhen building nested structures simply in order to pass them to a few C functions, I like to use with* and alloca* functions whenever possible.Michael,It looks like memory cleanup is being ignored in the example you linked to. newCString and mallocArray do not automatically free memory.
The following (untested) example temporarily marshals a C structure containing 2 pointers to null-terminated strings, and passes that to a supplied action. 4-byte pointers and ints are assumed:> withPerson :: Person -> (Ptr Person -> IO r) -> IO r> withPerson (Person fn ln age) f => -- Haskell's layout rules allow you to line these all up vertically.> -- Just place all your allocations before the first 'do'.> withCString fn $ \pfn ->> withCString ln $ \pln ->> allocaBytes 12 $ \ptr -> do> pokeByteOff ptr 0 pfn> pokeByteOff ptr 4 pln> pokeByteOff ptr 8 age> f ptrIn cases where you can't know ahead of time when the memory should be freed, you an use ForeignPtr. I think Real World Haskell gives an example of a nested structure marshaled in this way. By storing the ForeignPtr in a data object that gets carried around, you can guarantee that finalizes get called by the garbage collector only after you are done using them.I hope that helps.-- Michael SteeleOn Tue, May 5, 2015 at 6:22 AM, Michael Jones <mike@proclivis.com> wrote:Alexey,
That is an interesting insight. I suppose there are C API like that.
In my case, the FFI calls ioctl, which calls i2cdev_ioctl, which calls i2cdev_ioctl_rdwr.
The only function that can assume anything about the structure is i2cdev_ioctl_rdwr, which as you can see below copies the data, but does not free it.
So in this particular case, I need the FFI to free it.
On the other hand, I could write a wrapper in C that frees the structure if that is the way FFI is supposed to be used.
Does anyone know if there is a FFI solution that would not require a wrapper?
Mike
static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
unsigned long arg)
{
struct i2c_rdwr_ioctl_data rdwr_arg;
struct i2c_msg *rdwr_pa;
u8 __user **data_ptrs;
int i, res;
if (copy_from_user(&rdwr_arg,
(struct i2c_rdwr_ioctl_data __user *)arg,
sizeof(rdwr_arg)))
return -EFAULT;
On May 4, 2015, at 10:40 PM, Alexey Shmalko <rasen.dubi@gmail.com> wrote:
> Hi!
>
> Disclaimer: I haven't worked much with FFI, so I'd like someone
> confirmed my words.
>
> Seems that allocated memory in your example is supposed to be freed
> from inside C. It's not a memory leak.
>
> If I understand correctly documentation [1], malloc/free are just a
> simple wrappers around C's malloc/free. It's mallocForeignPtr that
> sets finalizer.
>
> Best regards,
> Alexey Shmalko
>
> [1]: https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/ffi-ghc.html
>
> On Tue, May 5, 2015 at 6:45 AM, Proclivis <mike@proclivis.com> wrote:
>> I should have mentioned GHC 7.8.3 Ubuntu 64bit
>>
>> Sent from my iPad
>>
>>> On May 4, 2015, at 9:42 PM, Proclivis <mike@proclivis.com> wrote:
>>>
>>> FFI Gurus,
>>>
>>> I created a c2hs FFI of a nested C structure, where struct A has a pointer to a struct B. To do so, I used a malloc, but I am unsure if the memory will be freed when the resulting Ptr is freed.
>>>
>>> The example at this link uses the same technique, so it will serve as an example.
>>>
>>> https://github.com/ifesdjeen/haskell-ffi-tutorial/blob/master/src/Example.hsc
>>>
>>> Line 48 and 51 do the malloc and assign the pointer in the struct, from inside a Storable poke implementation.
>>>
>>> But, there is no explicit free, nor a finalizer.
>>>
>>> Will the memory be freed when the Ptr of the Storable is freed?
>>>
>>> If it is, it implies that some magic keeps track of mallocs inside a poke, and creates finalizers. Or, this example leaks. If it leaks, how do I create a finalizer from inside a poke implementation?
>>>
>>> Mike
>>>
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe@haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe@haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
---- Michael Steele
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe