On Friday 01 September 2006 13:11, Caleb Tennis wrote: > > I think the QtRuby code for QStrings is probably wrong, but for 'char *'s > > I'm > > not sure as there are no rules for who 'owns' the string after the call > > has > > completed. Perhaps we can usually assume QtRuby should delete the 'char > > *', > > but special case when it shouldn't - tricky.. > > I've been pondering this for the past 15 minutes or so now, and I haven't > thought of any *good* solutions. I'm curious what PerlQt does to handle > this, if anything. Here the code from PerlQt 3.008 for 'char *' marshalling: static void marshall_charP(Marshall *m) { switch(m->action()) { case Marshall::FromSV: { SV *sv = m->var(); if(!SvOK(sv)) { m->item().s_voidp = 0; break; } if(m->cleanup()) m->item().s_voidp = SvPV_nolen(sv); else { STRLEN len; char *svstr = SvPV(sv, len); char *str = new char [len + 1]; strncpy(str, svstr, len); str[len] = 0; m->item().s_voidp = str; } } break; case Marshall::ToSV: { char *p = (char*)m->item().s_voidp; if(p) sv_setpv_mg(m->var(), p); else sv_setsv_mg(m->var(), &PL_sv_undef); if(m->cleanup()) delete[] p; } break; default: m->unsupported(); break; } } And here's the QString marshaller: static void marshall_QString(Marshall *m) { switch(m->action()) { case Marshall::FromSV: { SV* sv = m->var(); QString *s = 0; MAGIC* mg = 0; bool hasMagic = false; if(SvOK(sv) || m->type().isStack()) { if( SvTYPE(sv) == SVt_PVMG && (mg = mg_find(sv, PERL_MAGIC_tiedscalar)) && sv_derived_from(mg->mg_obj, "Qt::_internal::QString") ) { s = (QString*)SvIV((SV*)SvRV(mg->mg_obj)); hasMagic = true; } else { COP *cop = cxstack[cxstack_ix].blk_oldcop; if(SvUTF8(sv)) s = new QString(QString::fromUtf8(SvPV_nolen(sv))); else if(cop->op_private & HINT_LOCALE) s = new QString(QString::fromLocal8Bit(SvPV_nolen(sv))); else s = new QString(QString::fromLatin1(SvPV_nolen(sv))); if( !m->type().isConst() && !m->type().isStack() && !SvREADONLY(sv)) { SV* rv = newSV(0); sv_setref_pv(rv, "Qt::_internal::QString", (void*)s); sv_magic(sv, rv, PERL_MAGIC_tiedscalar, Nullch, 0); hasMagic = true; } } } else { if(!m->type().isConst()) { if(SvREADONLY(sv) && m->type().isPtr()) { m->item().s_voidp = 0; break; } s = new QString; if( !SvREADONLY(sv) ) { SV* rv = newSV(0); sv_setpv_mg(sv, ""); sv_setref_pv(rv, "Qt::_internal::QString", s); sv_magic(sv, rv, PERL_MAGIC_tiedscalar, Nullch, 0); hasMagic = true; } } else s = new QString; } m->item().s_voidp = s; m->next(); if(s && !hasMagic && m->cleanup()) delete s; } break; case Marshall::ToSV: { QString *s = (QString*)m->item().s_voidp; if(s) { COP *cop = cxstack[cxstack_ix].blk_oldcop; if(!(cop->op_private & HINT_BYTES)) { sv_setpv_mg(m->var(), (const char *)s->utf8()); SvUTF8_on(m->var()); } else if(cop->op_private & HINT_LOCALE) sv_setpv_mg(m->var(), (const char *)s->local8Bit()); else sv_setpv_mg(m->var(), (const char *)s->latin1()); } else sv_setsv_mg(m->var(), &PL_sv_undef); if(m->cleanup()) delete s; } break; default: m->unsupported(); break; } } Hmm, it looks like it has a bit more code - I wonder if I've missed some functionality converting to Ruby. It does use an isConst() check along with if( !SvREADONLY(sv) ) which doesn't have an equivalent in Ruby to set a boolean called 'hasMagic'. Then it only deletes the QString if hasMagic is false. -- Richard _______________________________________________ Kde-bindings mailing list Kde-bindings@kde.org https://mail.kde.org/mailman/listinfo/kde-bindings