geoffleach has asked for the wisdom of the Perl Monks concerning the following question:

O Monks, be pleased to offer wisdom to this lowly hacker:

I'm testing Audio::TagLib, and this statement:
print Audio::TagLib::ID3v2::Frame::size(1), "\n";
results in the runtime error:
THIS is not of type Audio::TagLib::ID3v2::Frame

I realize that this is not exactly a full example. I'm trying to keep things simple:-)

The short of it is this. We're accessing an XS interface to the C++ library taglib.. The XS code is:

unsigned int TagLib::ID3v2::Frame::size() CODE: RETVAL = THIS->size(); OUTPUT: RETVAL
and the C code derived from this is:
... if (sv_isobject(ST(0)) && sv_derived_from(ST(0), "Audio::TagLib::ID3v2 +::Fram THIS = INT2PTR(TagLib::ID3v2::Frame *, SvIV((SV *)SvRV(ST(0))) +); else Perl_croak(aTHX_ "THIS is not of type Audio::TagLib::ID3v2::Fr +ame");
So I see where the error is coming from, the question is: how is Perl determining what the type of THIS is? As far as I can tell, the various objects all have the correct specifications back to the C++ code. Additionally, is there a perlapi that will say what it thinks the type of THIS is?

Thanks.

Replies are listed 'Best First'.
Re: sv_derived_from gives a confsing result
by ikegami (Patriarch) on Mar 27, 2011 at 05:49 UTC

    You're passing «1» where an object of type «Audio::TagLib::ID3v2::Frame» is expected. The proper usage is

    $frame->size()
Re: sv_derived_from gives a confsing result
by syphilis (Archbishop) on Mar 27, 2011 at 06:13 UTC
    Additionally, is there a perlapi that will say what it thinks the type of THIS is?

    You can find out what ST(0) is with:
    warn("ST(0) is of type %s\n", HvNAME(SvSTASH(SvRV(ST(0)))));
    A demo:
    use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; void foo(SV * x) { dXSARGS; if (sv_isobject(ST(0))) warn("ST(0) is of type %s\n", HvNAME(SvSTASH(SvRV(ST(0))))); else warn("Not an object\n"); XSRETURN(0); } EOC use Math::BigInt; my $obj = Math::BigInt->new(17); foo($obj);
    Cheers,
    Rob
      Thanks, Rob. Your code, plus this:
      warn("not an object %s\n",(char *)SvPV_nolen(ST(0)));
      Revealed that ST(0) was '1', leading to the discovery that despite coding that looked like C++, Perl was not treating it as such. Seems to be related to the fact that there was no new() method.

      Sigh!

        Audio::TagLib::ID3v2::Frame::size(1) would be just as wrong in C++. The C++ equivalent of the correct code would be «frame->size()».
        Seems to be related to the fact that there was no new() method

        Sounds feasible. The method doesn't need to be called "new" (with C, at least), but if sv_isobject(sv) is to return true, then the reference (sv) does need to have been blessed into some package ... which is what "new" normally does, of course.

        Cheers,
        Rob