haskell / c2hs

c2hs is a pre-processor for Haskell FFI bindings to C libraries
http://hackage.haskell.org/package/c2hs
Other
199 stars 50 forks source link

Feature request: allow C finalizers that can call back into Haskell #241

Open vmchale opened 4 years ago

vmchale commented 4 years ago

I ran into the following error with my libarchive bindings:

error: a C finalizer called back into Haskell.
   This was previously allowed, but is disallowed in GHC 6.10.2 and later.
   To create finalizers that may call back into Haskell, use
   Foreign.Concurrent.newForeignPtr instead of Foreign.newForeignPtr.

Looking at generated code, it looks like c2hs uses Foreign.newForeignPtr by default:

import qualified Foreign.C.String as C2HSImp
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.ForeignPtr as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp

(This is from

{#pointer *archive as ArchivePtr foreign finalizer archive_free #}

among other things)

Would it be possible to use Foreign.Concurrent.newForeignPtr with a new keyword?

deech commented 4 years ago

I've looked into this a fair bit and adding the feature itself shouldn't be hard, I'm thinking about a syntax like:

{#pointer *archive as ArchivePtr foreign cfinalizer archive_free #}

The problem is that currently everything is imported qualified under the C2HSImp namespace and I'm struggling to come up with a solution less ugly than:

import qualified Foreign.Concurrent as C2HSImp_Foreign_Concurrent

and special casing that one newForeignPtr so it's generated as C2HSImp_Foreign_Concurrent.newForeignPtr.

I'll mull it over a little more but if I haven't come up with anything better by Sunday I'll just go with something like that. Should be transparent to most users.