Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Some functions in .xs file can't be found

by geoffleach (Scribe)
on Nov 13, 2013 at 00:58 UTC ( [id://1062287]=perlquestion: print w/replies, xml ) Need Help??

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

O Monks, please hear my question.

This concerns the distribution Audio::TagLib and the xs files therein, which interface to the C++ taglib library.

In one of the .xs files, some of the functions that are declared suffer from the (infamous?) error:

Can't locate object method "header" via package "Audio::TagLib::Tag"

Here's a snip of the .xs file. isEmpty() is recognized, header() and the functions that follow it in the file are not.

bool TagLib::ID3v2::Tag::isEmpty() CODE: RETVAL = THIS->isEmpty(); OUTPUT: RETVAL void TagLib::ID3v2::Tag::header() PREINIT: TagLib::ID3v2::Header * h; PPCODE: h = THIS->header(); ST(0) = sv_newmortal(); sv_setref_pv(ST(0), "Audio::TagLib::ID3v2::Header", (void *)h); SvREADONLY_on(SvRV(ST(0))); XSRETURN(1);

Applying nm(1) to the .so file suggests that header() should be located.

t _ZL36XS_Audio__TagLib__ID3v2__Tag_isEmptyP11interpreterP2cv t _ZL35XS_Audio__TagLib__ID3v2__Tag_headerP11interpreterP2cv

Everything in this particular .xs that follows isEmpty() suffers the same fate. However, in the .c file compiled from the .xs files (there are quite a few), other functions from other .xs files do not duffer the same fate.

Insight would be welcome.

Replies are listed 'Best First'.
Re: Some functions in .xs file can't be found
by syphilis (Archbishop) on Nov 13, 2013 at 02:22 UTC
    The XS file from which you quote is xs/id3v2tag.xs (package Audio::TagLib::ID3v2::Tag).
    There's also a declaration of TagLib::Tag::isEmpty() in xs/tag.xs (package Audio::TagLib::Tag) but no such declaration for the "header" function. I suspect this goes at least partway to explaining that isEmpty() can be loaded via package Audio::TagLib::Tag, but header() cannot.

    Cheers,
    Rob
Re: Some functions in .xs file can't be found
by BrowserUk (Patriarch) on Nov 13, 2013 at 01:44 UTC

    The function is defined as returning void, but then you call XSRETURN(1)

    Change:

    void TagLib::ID3v2::Tag::header()

    To:

    SV* TagLib::ID3v2::Tag::header()

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      No, it should be void. The C function doesn't return anything.

      #define XSRETURN(off) \ STMT_START { \ const IV tmpXSoff = (off); \ PL_stack_sp = PL_stack_base + ax + (tmpXSoff - 1); \ return; \ } STMT_END

      There are two ways of returning to Perl from an XS function:

      • Place it on the Perl stack.
        void foo() { ... mXPUSHs(sv); }
      • Return it from the C function. The typemap will place it on the Perl stack after any conversion and mortalizing it performs.
        SV* foo() { ... return sv; }

      The OP's code uses the former approach.

        Indeed. Thanks for the correction.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Some functions in .xs file can't be found
by bulk88 (Priest) on Nov 13, 2013 at 06:37 UTC
    xs/tag.xs has in it
    #include "tag.h" MODULE = Audio::TagLib PACKAGE = Audio::TagLib::Tag PROTOTYPES: ENABLE ################################################################ # # PUBLIC MEMBER FUNCTIONS # ################################################################ void TagLib::Tag::DESTROY() CODE: /* skip if READONLY flag on */ if(!SvREADONLY(SvRV(ST(0)))) delete THIS;
    see "PACKAGE = Audio::TagLib::Tag"? That is where the method calls will wind up in. But since this is C++ XS which I'm not familiar with, not C XS, I think the "TagLib::Tag::" get stripped off.

    As others said, your header() method in XS exists in a different class than you want it. Check the docs of your C++ library whether the TagLib::Tag class has a header method or not. According to http://taglib.github.io/api/classTagLib_1_1Tag.html it does not.

    BTW, you should also mention you are the CPAN maintainer of Audio-TagLib ;)
      OK, you got me. I confess I am the maintainer, alas.

      The good news is that I was shooting myself in the foot by using the wrong abstraction for the file being manipulated. I needed to use Audio::TagLib::MPEG::File rather than Audio::TagLib::FileRef. The latter supports more genereic tag methods, but not the ID3v2 methods, of which header() is one.

      The bad news is that now I have to write more tests. Sigh.

      Thanks to all who replied.

Re: Some functions in .xs file can't be found
by Anonymous Monk on Nov 13, 2013 at 01:40 UTC

    What relates TagLib::ID3v2::Tag::header with Audio::TagLib::Tag?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1062287]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-03-19 09:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found