/* declare as 5 member, not normal 8 to save image space*/ const static struct { int (*svt_get)(SV* sv, MAGIC* mg); int (*svt_set)(SV* sv, MAGIC* mg); U32 (*svt_len)(SV* sv, MAGIC* mg); int (*svt_clear)(SV* sv, MAGIC* mg); int (*svt_free)(SV* sv, MAGIC* mg); } my_vtbl = { NULL, NULL, NULL, NULL, NULL }; /* puts newsv, refcnt++ed (caller doesn't have to do it), in sv as hidden magic SV */ STATIC void setMgSV(pTHX_ SV * sv, SV * newsv) { MAGIC * mg; if(SvRMAGICAL(sv)) { /* implies SvTYPE >= SVt_PVMG */ mg = mg_findext(sv, PERL_MAGIC_ext, &my_vtbl); if(mg) { SV * oldsv; SvREFCNT_inc_simple_void_NN(newsv); oldsv = mg->mg_obj; mg->mg_obj = newsv; SvREFCNT_dec(oldsv); } else { goto addmg; } } else { addmg: sv_magicext(sv,newsv,PERL_MAGIC_ext,&my_vtbl,NULL,0); } } # xsub to attach a hidden SV in RV inside to the target SV of RV outside # both params must be references # void SetMagicSV(outside, inside) void SetMagicSV(...) PREINIT: SV * outside; SV * inside; CODE: if(items != 2) croak_xs_usage(cv, "outside, inside"); inside = POPs; outside = POPs; PUTBACK; if(SvROK(outside) && SvROK(inside)) { outside = SvRV(outside); inside = SvRV(inside); } else{ croak_xs_usage(cv, "outside, inside"); } setMgSV(aTHX_ outside, inside); return;