Next: , Previous: Using pragma foreign_proc for C, Up: Interfacing with C   [Contents]


15.10.1.5 Using pragma foreign_export for C

A ‘pragma foreign_export’ declaration for C has the form:

:- pragma foreign_export("C", MercuryMode, "C_Name").

For example,

:- pragma foreign_export("C", foo(in, in, out), "FOO").

For each Mercury module containing ‘pragma foreign_export’ declarations for C, the Mercury implementation will automatically create a header file for that module which declares a C function C_Name() for each of the ‘pragma foreign_export’ declarations. Each such C function is the C interface to the specified Mercury procedure.

The type signature of the C interface to a Mercury procedure is determined as follows. Mercury types are converted to C types according to the rules in C data passing conventions. Input arguments are passed by value. For output arguments, the caller must pass the address in which to store the result. If the Mercury procedure can fail, then its C interface function returns a truth value indicating success or failure. If the Mercury procedure is a Mercury function that cannot fail, and the function result has an output mode, then the C interface function will return the Mercury function result value. Otherwise the function result is appended as an extra argument. Arguments of type ‘io.state’ or ‘store.store(_)’ are not passed at all. (The reason for this is that these types represent mutable state, and in C modifications to mutable state are done via side effects, rather than argument passing.)

Calling polymorphically typed Mercury procedures from C is a little bit more difficult than calling ordinary (monomorphically typed) Mercury procedures. The simplest method is to just create monomorphic forwarding procedures that call the polymorphic procedures, and export them, rather than exporting the polymorphic procedures.

If you do export a polymorphically typed Mercury procedure, the compiler will prepend one ‘type_info’ argument to the parameter list of the C interface function for each distinct type variable in the Mercury procedure’s type signature. The caller must arrange to pass in appropriate ‘type_info’ values corresponding to the types of the other arguments passed. These ‘type_info’ arguments can be obtained using the Mercury ‘type_of’ function in the Mercury standard library module ‘type_desc’.

To use the C declarations produced see Using pragma foreign_decl for C.

Throwing an exception across the C interface is not supported. That is, if a Mercury procedure that is exported to C using ‘pragma foreign_export’ throws an exception which is not caught within that procedure, then you will get undefined behaviour.


Next: , Previous: Using pragma foreign_proc for C, Up: Interfacing with C   [Contents]