#if GMP_HAS_MAGICEXT
&& mg->mg_virtual == &vtbl_gmp
#endif
####
#if GMP_HAS_MAGICEXT
&& mg->mg_virtual != &vtbl_gmp
#endif
####
use warnings;
use Math::BigInt lib => 'GMP';
use Inline C => Config =>
LIBS => '-lgmp',
USING => 'ParseRegExp',
BUILD_NOISY => 1;
use Inline C => <<'EOC';
#include
#ifndef PERL_UNUSED_ARG
# define PERL_UNUSED_ARG(x) ((void)x)
#endif
#ifndef gv_stashpvs
# define gv_stashpvs(name, create) gv_stashpvn(name, sizeof(name) - 1, create)
#endif
#ifndef PERL_MAGIC_ext
# define PERL_MAGIC_ext '~'
#endif
#if defined(USE_ITHREADS) && defined(MGf_DUP)
# define GMP_THREADSAFE 1
#else
# define GMP_THREADSAFE 0
#endif
#ifdef sv_magicext
# define GMP_HAS_MAGICEXT 1
#else
# define GMP_HAS_MAGICEXT 0
#endif
#define NEW_GMP_MPZ_T RETVAL = malloc (sizeof(mpz_t));
#define NEW_GMP_MPZ_T_INIT RETVAL = malloc (sizeof(mpz_t)); mpz_init(*RETVAL);
#define GMP_GET_ARG_0 TEMP = mpz_from_sv(x);
#define GMP_GET_ARG_1 TEMP_1 = mpz_from_sv(y);
#define GMP_GET_ARGS_0_1 GMP_GET_ARG_0; GMP_GET_ARG_1;
#if GMP_THREADSAFE
STATIC int
dup_gmp_mpz (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
{
mpz_t *RETVAL;
PERL_UNUSED_ARG(params);
NEW_GMP_MPZ_T;
mpz_init_set(*RETVAL, *((mpz_t *)mg->mg_ptr));
mg->mg_ptr = (char *)RETVAL;
return 0;
}
#endif
#if GMP_HAS_MAGICEXT
STATIC MGVTBL vtbl_gmp = {
NULL, /* get */
NULL, /* set */
NULL, /* len */
NULL, /* clear */
NULL, /* free */
# ifdef MGf_COPY
NULL, /* copy */
# endif
# ifdef MGf_DUP
# if GMP_THREADSAFE
dup_gmp_mpz,
# else
NULL, /* dup */
# endif
# endif
# ifdef MGf_LOCAL
NULL, /* local */
# endif
};
#endif
void magic_status(void){
printf("GMP_HAS_MAGICEXT: %d\n", GMP_HAS_MAGICEXT);
}
STATIC mpz_t *
(SV *sv)
{
MAGIC *mg;
if (!sv_derived_from(sv, "Math::BigInt::GMP"))
croak("not of type Math::BigInt::GMP");
for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) {
if (mg->mg_type == PERL_MAGIC_ext
#if GMP_HAS_MAGICEXT
&& mg->mg_virtual != &vtbl_gmp
#endif
) {
#if GMP_HAS_MAGICEXT
return (mpz_t *)mg->mg_ptr;
#else
return INT2PTR(mpz_t *, SvIV((SV *)mg->mg_ptr));
#endif
}
}
return (mpz_t *)NULL;
}
void access_mpz(SV * sv) {
mpz_t *mpz;
if (!(mpz = mpz_from_sv_nofail(sv)))
croak("failed to fetch mpz pointer");
mpz_out_str(NULL, 10, mpz);
}
EOC
magic_status();
my $x = Math::BigInt->new('-' . ('9876543210123456789' x 4));
access_mpz($x->{value}); # Ignores $x->{sign}
####
GMP_HAS_MAGICEXT: 1
9876543210123456789987654321012345678998765432101234567899876543210123456789
####
GMP_HAS_MAGICEXT: 1
failed to fetch mpz pointer at try.pl line 125.