<p dir="ltr">First note: it's not GCC, but Haskell's GC.</p>
<p dir="ltr">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.<br>
</p>

<br><div class="gmail_quote">On Sun, May 10, 2015, 18:58 Proclivis <<a href="mailto:mike@proclivis.com" target="_blank">mike@proclivis.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>Thanks guys,</div><div><br></div><div>I looks like there are basically 2 ways to do this:</div><div><br></div><div>1) Build a structure of ForeignPtr with finalizers that will be freed whenever the GCC feels like it</div><div>2) Nest allocations and the will free at the end of IO </div><div><br></div><div>I 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?</div><div><br></div><div>Mike<br><br>Sent from my iPad</div></div><div dir="auto"><div><br>On May 5, 2015, at 10:10 AM, Michael Steele <<a href="mailto:mikesteele81@gmail.com" target="_blank">mikesteele81@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr"><div><div><div>Michael,<br><br></div>It looks like memory cleanup is being ignored in the example you linked to. newCString and mallocArray do not automatically free memory.<br><br></div>When building nested structures simply in order to pass them to a few C functions, I like to use with* and alloca* functions whenever possible.<br><br>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:<br><br></div><span style="font-family:monospace,monospace">> data Person = Person String String Int<br></span><div><span style="font-family:monospace,monospace">> withPerson :: Person -> (Ptr Person -> IO r) -> IO r<br></span></div><div><span style="font-family:monospace,monospace">> withPerson (Person fn ln age) f =<br></span></div><div><span style="font-family:monospace,monospace">>     -- Haskell's layout rules allow you to line these all up vertically.<br></span></div><div><span style="font-family:monospace,monospace">>     -- Just place all your allocations before the first 'do'.<br></span></div><div><span style="font-family:monospace,monospace">>     withCString fn $ \pfn -><br></span></div><div><span style="font-family:monospace,monospace">>     withCString ln $ \pln -><br></span></div><div><span style="font-family:monospace,monospace">>     allocaBytes 12 $ \ptr -> do<br></span></div><div><span style="font-family:monospace,monospace">>     pokeByteOff ptr 0 pfn<br></span></div><div><span style="font-family:monospace,monospace">>     pokeByteOff ptr 4 pln<br></span></div><div><span style="font-family:monospace,monospace">>     pokeByteOff ptr 8 age<br></span></div><div><span style="font-family:monospace,monospace">>     f ptr</span><br><br></div><div>In 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.<br><br></div><div>I hope that helps.<br><br></div><div>-- Michael Steele<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 5, 2015 at 6:22 AM, Michael Jones <span dir="ltr"><<a href="mailto:mike@proclivis.com" target="_blank">mike@proclivis.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Alexey,<br>
<br>
That is an interesting insight. I suppose there are C API like that.<br>
<br>
In my case, the FFI calls ioctl, which calls i2cdev_ioctl, which calls i2cdev_ioctl_rdwr.<br>
<br>
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.<br>
<br>
So in this particular case, I need the FFI to free it.<br>
<br>
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.<br>
<br>
Does anyone know if there is a FFI solution that would not require a wrapper?<br>
<br>
Mike<br>
<br>
static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,<br>
                unsigned long arg)<br>
{<br>
        struct i2c_rdwr_ioctl_data rdwr_arg;<br>
        struct i2c_msg *rdwr_pa;<br>
        u8 __user **data_ptrs;<br>
        int i, res;<br>
<br>
        if (copy_from_user(&rdwr_arg,<br>
                           (struct i2c_rdwr_ioctl_data __user *)arg,<br>
                           sizeof(rdwr_arg)))<br>
                return -EFAULT;<br>
<div><div><br>
<br>
<br>
On May 4, 2015, at 10:40 PM, Alexey Shmalko <<a href="mailto:rasen.dubi@gmail.com" target="_blank">rasen.dubi@gmail.com</a>> wrote:<br>
<br>
> Hi!<br>
><br>
> Disclaimer: I haven't worked much with FFI, so I'd like someone<br>
> confirmed my words.<br>
><br>
> Seems that allocated memory in your example is supposed to be freed<br>
> from inside C. It's not a memory leak.<br>
><br>
> If I understand correctly documentation [1], malloc/free are just a<br>
> simple wrappers around C's malloc/free. It's mallocForeignPtr that<br>
> sets finalizer.<br>
><br>
> Best regards,<br>
> Alexey Shmalko<br>
><br>
> [1]: <a href="https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/ffi-ghc.html" target="_blank">https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/ffi-ghc.html</a><br>
><br>
> On Tue, May 5, 2015 at 6:45 AM, Proclivis <<a href="mailto:mike@proclivis.com" target="_blank">mike@proclivis.com</a>> wrote:<br>
>> I should have mentioned GHC 7.8.3 Ubuntu 64bit<br>
>><br>
>> Sent from my iPad<br>
>><br>
>>> On May 4, 2015, at 9:42 PM, Proclivis <<a href="mailto:mike@proclivis.com" target="_blank">mike@proclivis.com</a>> wrote:<br>
>>><br>
>>> FFI Gurus,<br>
>>><br>
>>> 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.<br>
>>><br>
>>> The example at this link uses the same technique, so it will serve as an example.<br>
>>><br>
>>> <a href="https://github.com/ifesdjeen/haskell-ffi-tutorial/blob/master/src/Example.hsc" target="_blank">https://github.com/ifesdjeen/haskell-ffi-tutorial/blob/master/src/Example.hsc</a><br>
>>><br>
>>> Line 48 and 51 do the malloc and assign the pointer in the struct, from inside a Storable poke implementation.<br>
>>><br>
>>> But, there is no explicit free, nor a finalizer.<br>
>>><br>
>>> Will the memory be freed when the Ptr of the Storable is freed?<br>
>>><br>
>>> 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?<br>
>>><br>
>>> Mike<br>
>>><br>
>>> _______________________________________________<br>
>>> Haskell-Cafe mailing list<br>
>>> <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
>><br>
>> _______________________________________________<br>
>> Haskell-Cafe mailing list<br>
>> <a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div><div>-- Michael Steele</div></div>
</div>
</div></blockquote></div>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>