[C2hs] [c2hs] #46: No way to create a foreign pointer for input and have it as an out parameter
c2hs
cvs-ghc at haskell.org
Wed Jul 4 19:45:25 CEST 2012
#46: No way to create a foreign pointer for input and have it as an out
parameter
--------------------+-------------------------------------------------------
Reporter: guest | Type: defect
Status: new | Priority: normal
Milestone: | Component: general
Version: 0.16.0 | Keywords:
--------------------+-------------------------------------------------------
I have quite a few C functions like this:
... func(oid *, ...);
oid refers to a non-opaque C struct, and these functions treat it as an
out parameter; a C caller would define an instance of the struct (knowing
its size) and pass the address of that structure to have it filled in.
I'd like to allocate memory for this struct using mallocForeignPtrBytes {#
sizeof oid #}, pass the underlying Ptr to the function, and then return
the foreign pointer wrapped in an opaque type (defined using {# pointer
... foreign newtype #}). Note that the documentation for
mallocForeignPtrBytes specifically says that GHC implements it much more
efficiently than a standard ForeignPtr with a finalizer of finalizerFree;
otherwise, I could just use malloc and then wrap the pointer on the way
out.
As far as I can tell, a {# fun ... #} wrapper cannot implement this
pattern. Any output marshaller has to work using the same value passed to
the function, which in this case would be a Ptr, not a ForeignPtr. Thus,
I can't both create an OID in the input marshaller (using a - so the
caller doesn't have to pass one) and return that OID from the function.
At the moment, I've come up with three workarounds, none of which work
very well:
- Write a {# fun ... #} wrapper using withOID* and write a Haskell wrapper
function that calls newOID first, requiring an extra five lines for every
function using an OID.
- Give up on mallocForeignPtrBytes and use malloc on input and
newForeignPtr on output, with resulting inefficiency (the library uses a
*lot* of these structures).
- Use alloca on input, and have the output marshaller use
mallocForeignPtrBytes and make a copy. Efficient use of memory and
efficient reclamation, but an extra copy per call.
Ideally, I'd prefer to have a way to declare this pattern directly in a
marshaller. I'd suggest adding a new symbol to apply to the input
marshaller, which allows it to provide an output directly.
--
Ticket URL: <http://hackage.haskell.org/trac/c2hs/ticket/46>
c2hs <http://www.cse.unsw.edu.au/~chak/haskell/c2hs/>
C->Haskell, An Interface Generator for Haskell
More information about the C2hs
mailing list