syphilis has asked for the wisdom of the Perl Monks concerning the following question:
but that condition never holds for me, so I've changed it to:#if GMP_HAS_MAGICEXT && mg->mg_virtual == &vtbl_gmp #endif
though simply commenting out that code also works fine, and might be safer.#if GMP_HAS_MAGICEXT && mg->mg_virtual != &vtbl_gmp #endif
For me this outputs (after compilation):use warnings; use Math::BigInt lib => 'GMP'; use Inline C => Config => LIBS => '-lgmp', USING => 'ParseRegExp', BUILD_NOISY => 1; use Inline C => <<'EOC'; #include <gmp.h> #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}
If I revert to the original mpz_from_sv_nofail() code I get:GMP_HAS_MAGICEXT: 1 9876543210123456789987654321012345678998765432101234567899876543210123 +456789
Cheers,GMP_HAS_MAGICEXT: 1 failed to fetch mpz pointer at try.pl line 125.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Math::BigInt::GMP - direct access to the gmp integer value
by Anonymous Monk on Jan 10, 2016 at 04:14 UTC | |
by syphilis (Archbishop) on Jan 10, 2016 at 05:26 UTC | |
by Anonymous Monk on Jan 10, 2016 at 05:53 UTC | |
|
Re: Math::BigInt::GMP - direct access to the gmp integer value
by Will_the_Chill (Pilgrim) on Jan 10, 2016 at 23:58 UTC | |
|
Re: Math::BigInt::GMP - direct access to the gmp integer value
by Anonymous Monk on Jan 11, 2016 at 06:41 UTC | |
by syphilis (Archbishop) on Jan 11, 2016 at 23:41 UTC |