Jefferson Heard wrote: > I have the following functions in C: > > OGRErr OGR_G_CreateFromWkb (unsigned char *, OGRSpatialReferenceH, > OGRGeometryH *, int) > OGRErr OGR_G_CreateFromWkt (char **, OGRSpatialReferenceH, OGRGeometryH > *) > void OGR_G_DestroyGeometry (OGRGeometryH) > OGRGeometryH OGR_G_CreateGeometry (OGRwkbGeometryType) > > The normal sequence of calls is > > OGRGeometryH handle = OGR_G_CreateGeometry(SOME_TYPE); > // do stuff > OGR_G_DestroyGeometry(handle); > > OR > > OGR_G_CreateFromWkb(blob, ref, &handle, 0); > // do stuff > OGR_G_DestroyGeometry(handle); > > As you can see, in one case, I have to pass in a pointer to the > returned handle, and not just the handle. How can I accomplish this > feat using a single type? > > I had > > data OGRGeometryH > type Geometry = Ptr OGRGeometryH
Almost: Assuming that OGRGeometryH is some sort of pointer, e.g. typedef struct OGRGeometry *OGRGeometryH you could write: > data OGRGeometry > type OGRGeometryH = Ptr OGRGeometry where OGRGeometryH is the type that you API exports. > foreign import ccall > oGR_G_CreateFromWkb :: ...whatever... -> Ptr OGRGeometryH -> OGRErr Note that Ptr OGRGeometryH is in fact a pointer to a pointer, just as the C type demands. When calling such a procedure you must first allocate space. This is most elegantly done using alloca (I have added some basic error handling, otherwise the value returned might be undefined): > createFromWbk :: ...argtypes... -> Either OGRErr OGRGeometryH > createFromWbk ...args... = alloca $ \ptr -> do > -- in this code block you can peek and poke the ptr; > -- space will be deallocated after block exits > res <- oGR_G_CreateFromWkb ...args... ptr > if checkResultOK res > then do > -- this can be shortened to: liftM Right $ peek ptr > -- or: peek ptr >>= return . Right > h <- peek ptr > return (Right h) > else return (Left res) (Instead of returning an Either type you could throw exceptions, but you didn't ask about error handling, did you ?-) Cheers Ben _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe