in reply to XSUBs with variable input types

If at the perl level your Bar and Baz also inherit from Foo, the call will get accepted in fact. Now if at the C level calling getName will also work on e.g. bar objects even though they are currently in a foo typed variable, then all is fine (depends on how the C level inheritance is done, usually this would work).

But even if it doesn't, you could always build your own polymorphic GetName by simply saying the argument is an SV * and determining the exact type by yourself with something like (untested):

... GetName(SV *thingy) PREINIT: IV tmp; CODE: if (sv_derived_from(thingy, "Foo")) { fooRef foo; tmp = SvIV((SV*) SvRV(thingy)); foo = INT2PTR(fooRef, tmp); getName(foo); } else if (sv_derived_from(thingy, "Bar")) { barRef bar; tmp = SvIV((SV*) SvRV(thingy)); bar = INT2PTR(barRef, tmp); getName(bar); } else if (sv_derived_from(thingy, "Baz")) { bazRef baz; tmp = SvIV((SV*) SvRV(thingy)); baz = INT2PTR(bazRef, tmp); getName(baz); } else croak("Some unhandled argument type message"); ...

Doing it like that is not necessarily a good idea though. If Foo, Bar and Baz form the basis of separate object hierarchies at the perl level, it probably makes more sense to have a GetName for each object type in your XS code. No need to pollute the accessor name with the type though, just have them all in a different MODULE/PACKAGE section.

Replies are listed 'Best First'.
Re^2: XSUBs with variable input types
by crenz (Priest) on Oct 25, 2004 at 09:01 UTC

    Thanks for the hints! However, Perl can't know about the relationship with the Perl classes, since in my typemap, I declared the following:

    fooRef T_PTROBJ barRef T_PTROBJ bazRef T_PTROBJ

    How should I go about telling Perl that fooRef actually is a Foo object?

      Please read the section "Perl Objects And C Structures" in perlxs (ignore the part about "Ptr" getting appended). You probably want your typemap to say:
      Foo T_PTROBJ Bar T_PTROBJ Baz T_PTROBJ
      and then have typedefs in your XS code to map these to your C level types. The perl level object hierarchy you define in the normal way in .pm files with e.g. things like:
      package Bar; ... use base qw(Foo); ...
      (and supposedly Foo.pm does the dynaload)

      Again, this last is not necessarily a good idea unless it's ok to call Foo functions on Bar objects for XS methods that exist in Foo but not in Bar (they will get called through inheritance if you apply that method to a Bar object)

        Thanks a lot, that works exactly as expected! I use @ISA for inheritance, but apart from that adopted your solution.