extern/1 declaration

Synopsis

:-extern(+ExternSpec)

Declares a Prolog predicate to be callable from functions written in other languages.

Arguments


ExternSpec extern_spec [MOD]
a term of the form Name(Argspec, Argspec, ...)

Name
the name of the Prolog predicate
Argspec
an argument specification for each argument of the predicate. Each should be one of the following where T is a foreign type name.
                +integer    +float    +single   +double
                -integer    -float    -single   -double
               
                +atom       +term     +string
                -atom       -term     -string
               
                +string     +address(T)
                -string     -address(T)
               

Description

extern/1 is used to make Prolog predicates callable from functions written in other languages. extern/1 must appear as a compile-time declaration; furthermore, it may not appear in files loaded into runtime systems. The user has to declare as callable each Prolog predicate that is to be called from foreign functions. Any Prolog predicate can be declared to be callable from foreign functions, including system built-ins and predicates that do not currently have definitions. Predicates must be declared callable before they can actually be called from a function written in a foreign language.

Arguments are passed to the foreign interface as specified in ExternSpec:


+
indicates that an argument is to be passed to Prolog from a foreign function.
-
indicates that an argument is to be passed from Prolog to the foreign function.

Unlike the interface enabling Prolog to call functions written in other languages, when foreign functions call Prolog there are no return values or corresponding designators in ExternSpec.

When a Prolog predicate is declared to be callable, an interface predicate is created in the current module. The arity of the interface predicate is the same as that of the Prolog predicate. The name of the interface predicate is that of the Prolog predicate with an underscore prepended. The interface predicate is made available to the user as a hook to the "callability" of the Prolog predicate; for instance, the callability of the predicate can be saved by putting the interface predicate in a QOF file via save_predicates/2, then reloaded like any other predicate. The interface predicate can also be abolished like any other predicate; this also has the effect of making the previously callable Prolog predicate no longer available to foreign functions. A call to any interface predicate simply fails.

For more details about passing arguments from the foreign interface, see the chapter on the foreign language interface.

Exceptions


instantiation_error
ExternSpec is uninstantiated

Some Argspec in ExternSpec is uninstantiated or is a term that is insufficiently instantiated

type_error
ExternSpec is instantiated but is not a callable term

Some Argspec in ExternSpec is not a callable term

domain_error
Some Argspec in ExternSpec is not one of the forms listed above

Examples

It can be quite useful to make the system built-in call/1 available to foreign functions. Combined with term manipulation in C, doing so provides an evaluator for arbitrary Prolog queries. This can be done by loading a Prolog file containing the declaration

     :- extern(call(+term)).
     

Prolog's call/1 is then available to C via a function like

     call_prolog(term)
     QP_term_ref term;
     {
         QP_pred_ref call;
         call = QP_predicate("call",1,"user");
         QP_query(call, term);
     }
     

For the sake of brevity, this example does not check return values for failure or errors. Doing so is generally recommended. Of course, as is the case in Prolog, it is faster to call a Prolog predicate directly.