http://www.perlmonks.org?node_id=974296


in reply to Re^18: supporting quads on 32 bit Perl
in thread supporting quads on 32 bit Perl

0.22 from CPAN will not compile. All the errors follow the same format.
Int64.xs(974) : error C2275: 'int64_t' : illegal use of this type as a +n expressi on Int64.xs(22) : see declaration of 'int64_t'
Given this XS code
SV *mi64_right(self, other, rev = &PL_sv_no) SV *self SV *other SV *rev CODE: int64_t a; uint64_t b; if (SvTRUE(rev)) { a = SvI64(aTHX_ other); b = SvU64x(self); } else { a = SvI64x(self); b = SvU64(aTHX_ other); }
which produces this C code
XS(XS_Math__Int64__right); /* prototype to pass -Wmissing-prototypes * +/ XS(XS_Math__Int64__right) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items < 2 || items > 3) croak_xs_usage(cv, "self, other, rev = &PL_sv_no"); { SV * self = ST(0); SV * other = ST(1); SV * rev; SV * RETVAL; if (items < 3) rev = &PL_sv_no; else { rev = ST(2); } #line 974 "Int64.xs" int64_t a; uint64_t b; if (SvTRUE(rev)) { a = SvI64(aTHX_ other); b = SvU64x(self); } else { a = SvI64x(self); b = SvU64(aTHX_ other); }
The error is obvious. You need to use PREINIT. Never rely on typemap entries being 1 liners and initialization not being deferred by XSPP. You can open new blocks, create new C autos, and run 1/4 page of code from a typemap entry. You can even run perl code to generate the type entry in the XS sub. For example to get accept a reference and its target.
T_REFANDSV ".(unshift(@line, ( 'PREINIT:', ' SV * '.$var.'Ref;', 'INPUT:')),''). "${\$var}Ref = $arg; if (SvROK(${\$var}Ref)) $var = (SV*)SvRV(${\$var}Ref); else Perl_croak(aTHX_ \"%s: %s is not a reference\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\");