- Documentation
- Reference manual
- Foreign Language Interface
- The Foreign Include File
- Argument Passing and Control
- Atoms and functors
- Analysing Terms via the Foreign Interface
- Constructing Terms
- Unifying data
- Convenient functions to generate Prolog exceptions
- BLOBS: Using atoms to store arbitrary binary data
- Exchanging GMP numbers
- Calling Prolog from C
- Discarding Data
- Foreign Code and Modules
- Prolog exceptions in foreign code
- Catching Signals (Software Interrupts)
- Miscellaneous
- Errors and warnings
- Environment Control from Foreign Code
- Querying Prolog
- Registering Foreign Predicates
- Foreign Code Hooks
- Storing foreign data
- Embedding SWI-Prolog in other applications
- The Foreign Include File
- Foreign Language Interface
- Packages
- Reference manual
11.4.8 Exchanging GMP numbers
If SWI-Prolog is linked with the GNU Multiple Precision Arithmetic
Library (GMP, used by default), the foreign interface provides functions
for exchanging numeric values to GMP types. To access these functions
the header <gmp.h>
must be included before
<SWI-Prolog.h>
. Foreign code using GMP linked to
SWI-Prolog asks for some considerations.
- SWI-Prolog normally rebinds the GMP allocation functions using
mp_set_memory_functions(). This means SWI-Prolog must be initialised
before the foreign code touches any GMP function. You can call
\cfuncref{PL_action}{PL_GMP_SET_ALLOC_FUNCTIONS, TRUE}
to force Prolog's GMP initialization without doing the rest of the Prolog initialization. If you do not want Prolog rebinding the GMP allocation, call\cfuncref{PL_action}{PL_GMP_SET_ALLOC_FUNCTIONS, FALSE}
before initializing Prolog. - On Windows, each DLL has its own memory pool. To make exchange of GMP numbers between Prolog and foreign code possible you must either let Prolog rebind the allocation functions (default) or you must recompile SWI-Prolog to link to a DLL version of the GMP library.
Here is an example exploiting the function mpz_nextprime():
#include <gmp.h> #include <SWI-Prolog.h> static foreign_t next_prime(term_t n, term_t prime) { mpz_t mpz; int rc; mpz_init(mpz); if ( PL_get_mpz(n, mpz) ) { mpz_nextprime(mpz, mpz); rc = PL_unify_mpz(prime, mpz); } else rc = FALSE; mpz_clear(mpz); return rc; } install_t install() { PL_register_foreign("next_prime", 2, next_prime, 0); }
- int PL_get_mpz(term_t t, mpz_t mpz)
- If t represents an integer, mpz is filled with the
value and the function returns
TRUE
. Otherwise mpz is untouched and the function returnsFALSE
. Note that mpz must have been initialised before calling this function and must be cleared using mpz_clear() to reclaim any storage associated with it. - int PL_get_mpq(term_t t, mpq_t mpq)
- If t is an integer or rational number (term
rdiv/2
), mpq is filled with the normalised rational number and the function returnsTRUE
. Otherwise mpq is untouched and the function returnsFALSE
. Note that mpq must have been initialised before calling this function and must be cleared using mpq_clear() to reclaim any storage associated with it. - int PL_unify_mpz(term_t t, mpz_t mpz)
- Unify t with the integer value represented by mpz
and return
TRUE
on success. The mpz argument is not changed. - int PL_unify_mpq(term_t t, mpq_t mpq)
- Unify t with a rational number represented by mpq
and return
TRUE
on success. Note that t is unified with an integer if the denominator is 1. The mpq argument is not changed.