Pointer Hooks

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : Pointer Hooks
Previous: Set Hooks
Next: Class Hooks

## 2.10. Pointer Hooks

> `{#pointer [*] cid [as hsid] [foreign | stable] [newtype | -> hsid2] [nocode]#}`

A pointer hook facilitates the mapping of C to Haskell pointer types. In particular, it enables the use of `ForeignPtr` and `StablePtr` types and defines type name translations for pointers to non-basic types. In general, such a hook establishes an association between the C type cid or `*`cid and the Haskell type hsid, where the latter defaults to cid if not explicitly given. The identifier cid will usually be a type name, but in the case of `*`cid may also be a struct, union, or enum tag. If both a type name and a tag of the same name are available, the type name takes precedence. Optionally, the Haskell representation of the pointer can be by a `ForeignPtr` or `StablePtr` instead of a plain `Ptr`. If the `newtype` tag is given, the Haskell type hsid is defined as a `newtype` rather than a transparent type synonym. In case of a `newtype`, the type argument to the Haskell pointer type will be hsid, which gives a cyclic definition, but the type argument is here really only used as a unique type tag. Without `newtype`, the default type argument is `()`, but another type can be specified after the symbol `->`.

For example, we may have

> `

>     {#pointer *GtkObject as Object newtype#}

> `

This will generate a new type `Object` as follows:

> `

>     newtype Object = Object (Ptr Object)

> `

which enables exporting `Object` as an abstract type and facilitates type checking at call sites of imported functions using the encapsulated pointer. The latter is achieved by C->Haskell as follows. The tool remembers the association of the C type `*GtkObject` with the Haskell type `Object`, and so, it generates for the C function

> `

>     void gtk_unref_object (GtkObject *obj);

> `

the import declaration

> `

>     foreign import gtk_unref_object :: Object -> IO ()

> `

This function can obviously only be applied to pointers of the right type, and thus, protects against the common mistake of confusing the order of pointer arguments in function calls.

However, as the Haskell FFI does not permit to directly pass `ForeignPtr`s to function calls or return them, the tool will use the type `Ptr HsName` in this case, where `HsName` is the Haskell name of the type. So, if we modify the above declaration to be

> `

>     {#pointer *GtkObject as Object foreign newtype#}

> `

the type `Ptr Object` will be used instead of a plain `Object` in import declarations; i.e., the previous `import` declaration will become

> `

>     foreign import gtk_unref_object :: Ptr Object -> IO ()

> `

To simplify the required marshalling code for such pointers, the tool automatically generates a function

> `

>     withObject :: Object -> (Ptr Object -> IO a) -> IO a

> `

As an example that does not represent the pointer as an abstract type, consider the C type declaration:

> `

>     typedef struct {int x, y;} *point;

> `

We can represent it in Haskell as

> `

>     data Point = Point {x :: Int, y :: Int}
>     {#pointer point as PointPtr -> Point#}

> `

which will translate to

> `

>     data Point = Point {x :: Int, y :: Int}
>     type PointPtr = Ptr Point

> `

and establish a type association between `point` and `PointPtr`.

If the keyword `nocode` is added to the end of a pointer hook, C->Haskell will not emit a type declaration. This is useful when a C->Haskell module wants to make use of an existing type declaration in a binding not generated by C->Haskell (i.e., where there are no `.chi` files).

Restriction: The name cid cannot be a basic C type (such as `int`), it must be a defined name.

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : Pointer Hooks
Previous: Set Hooks
Next: Class Hooks