[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