The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
TYPEMAP
DH_gmp_t *        T_DH_GMP
DH_gmp_value      T_DH_GMP_VALUE

INPUT
T_DH_GMP
        if (sv_derived_from($arg, \"Crypt::DH::GMP\")) {
            IV tmp = SvIV((SV *) SvRV($arg));
            $var = INT2PTR($type, tmp);
        } else {
            croak(\"$var is not of type Crypt::DH::GMP\");
        }

T_DH_GMP_VALUE
        if (! SvPOK($arg)) {
            croak(\"$var is not a string!\");
        }
        mpz_init_set_str($var, SvPV_nolen($arg), 10);

OUTPUT
T_DH_GMP
        if ($var == NULL) {
            croak(\"$var is NULL?!\");
        } else {
            sv_setref_pv($arg, class, INT2PTR(void *, $var));
        }

T_DH_GMP_VALUE
        {
            char *buf;
            char *buf_end;
            int len;

            mpz_t *tmp = $arg; /* Set aside for temporary use */

            /* len is always >= 1, and might be off (greater) by one than real len */
            len = mpz_sizeinbase(*tmp, 10);
            $arg = newSV(len);  /* alloc len + 1 bytes */
            SvPOK_on($arg);
            buf = SvPVX($arg); /* get ptr to storage */
            buf_end = buf + len - 1; /* end of storage (-1) */
            mpz_get_str(buf, 10, *tmp);
            if (*buf_end == 0) {
                len--; /* got one shorter than expected */
            }
            
            SvCUR_set($arg, len);
        }