Next: , Previous: , Up: Foreign language interface   [Contents]


14.7 Adding foreign declarations

Foreign language declarations (such as type declarations, header file inclusions or macro definitions) can be included in the Mercury source file as part of a ‘foreign_decl’ declaration of the form

:- pragma foreign_decl("Lang", DeclCode).

This declaration will have effects equivalent to including the specified DeclCode in an automatically-generated source file of the specified programming language, in a place appropriate for declarations, and linking that source file with the Mercury program (after having compiled it with a compiler for the specified programming language, if appropriate).

Entities declared in ‘pragma foreign_decl’ declarations are visible in ‘pragma foreign_code’, ‘pragma foreign_type’, ‘pragma foreign_proc’, and ‘pragma foreign_enum’ declarations that specify the same foreign language and occur in the same Mercury module.

By default, the contents of ‘pragma foreign_decl’ declarations are also visible in the same kinds of declarations in other modules that import the module containing the ‘pragma foreign_decl’ declaration. This is because they may be required to make sense of types defined using ‘pragma foreign_type’ and/or predicates defined using ‘pragma foreign_code’ in the containing module, and these may be visible in other modules, especially in the presence of intermodule optimization,

If you do not want the contents of a ‘pragma foreign_decl’ declaration to be visible in foreign language code in other modules, you can use the following variant of the declaration:

:- pragma foreign_decl("Lang", local, DeclCode).

Note: currently only the C and Erlang backends support this variant of the ‘pragma foreign_decl’ declaration.

The declarations for Mercury predicates or functions exported to a foreign language using a ‘pragma foreign_export’ declaration are visible to foreign code in a ‘pragma foreign_code’ or ‘pragma foreign_proc’ declaration of the same module and also in those of any sub-modules. They are not visible to the foreign code in ‘pragma foreign_code’ or ‘pragma foreign_proc’ declarations in any other module. They can be made visible using a declaration of the form:

:- pragma foreign_import_module("Lang", ImportedModule).

where ImportedModule is the name of the module containing the ‘pragma foreign_export’ declarations.

If Lang is "C" this is equivalent to

:- pragma foreign_decl("C", "#include ""ImportedModule.mh""").

where ImportedModule.mh is the automatically generated header file containing the C declarations for the predicates and functions exported to C.

pragma foreign_import_module’ should be used instead of the explicit #include because ‘pragma foreign_import_module’ tells the implementation that ImportedModule.mh must be built before the object file for the module containing the ‘pragma foreign_import_module’ declaration.

A cycle of ‘pragma foreign_import_module’, where the language is ‘"C#"’ or ‘"Java"’, is not permitted.

Note that the Melbourne Mercury implementation often implicitly inserts ‘pragma foreign_import_module’ declarations but programmers should not write code that depends upon this behaviour; ‘pragma foreign_import_module’ declarations should always be explicitly included if needed.


Next: , Previous: , Up: Foreign language interface   [Contents]