Discussion:
OVERLOAD?
(too old to reply)
Scott Lanning
2007-09-07 09:40:38 UTC
Permalink
Hello extension interfacers,

I'm doing bindings for a C++ library,
and I have many problems/questions, of which this is one.

I've tried following the docs for "The OVERLOAD: Keyword"
in `perldoc perlxs`; however, I don't really understand
the syntax for it:

SV *
cmp (lobj, robj, swap)
My_Module_obj lobj
My_Module_obj robj
IV swap
OVERLOAD: cmp <=>
{ /* function defined here */}

I always get weird errors suggesting a parsing problem.
Here's a final bizarre attempt to mimic the above:

bool
cmp(lobj, robj, swap)
Vector3 * lobj
Vector3 * robj
IV swap
OVERLOAD: ==
{
RETVAL = (*lobj == *robj);
}

Before that I'd tried also with

Vector3::cmp(lobj, robj, swap)

and without the curly braces but with CODE and OUTPUT blocks.

I ended up just making an `eq_xs' function and using
that with `use overload' from the Perl module,
but for no particular reason I think I'd prefer
to do it all from XS if possible.
Steve Fink
2007-09-08 21:24:13 UTC
Permalink
What error message are you getting?

If anything in the overloaded function is not in your typemap, the
generated C code is completely bogus (syntactically incorrect.)

But the following code seems to do something sensible, when processed with

xsubpp -typemap /usr/share/perl/5.8.8/ExtUtils/typemap overload-test.xs

----

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

MODULE = Extend PACKAGE = Extend

bool
compare(lobj,robj,swap)
char *lobj
char *robj
IV swap
OVERLOAD: ==
{
RETVAL = (*lobj == *robj);
}
Scott Lanning
2007-09-10 09:15:54 UTC
Permalink
Post by Steve Fink
What error message are you getting?
I think it's a bug (or lack of C++ functionality) in xsubpp,
but I'm not ruling out a self-introduced problem. :)

I added this to xs/Vector3.xs :

bool
equals(lobj, robj, swap)
Vector3 * lobj
Vector3 * robj
IV swap
OVERLOAD: ==
CODE:
RETVAL = (*lobj == *robj);
OUTPUT:
RETVAL

(Note: I couldn't figure out the correct syntax
either from the documentation nor from *attempting*
to read the code for `xsubpp`.)

When I do `make`, the error is :

Ogre.c: In function 'void XS_Ogre__Animation_nil(PerlInterpreter*, CV*)':
Ogre.c:11158: error: 'ax' was not declared in this scope
Ogre.c: In function 'void boot_Ogre(PerlInterpreter*, CV*)':
Ogre.c:11180: error: cannot convert 'sv' to 'SV*' for argument '3' to 'void
Perl_sv_setsv_flags(PerlInterpreter*, SV*, SV*, I32)'
make: *** [Ogre.o] Error 1


In Ogre.c, I find :

XS(XS_Ogre__Animation_nil); /* prototype to pass -Wmissing-prototypes */
XS(XS_Ogre__Animation_nil)
{
XSRETURN_EMPTY; <--- line 11158
}


Note that it has generated OVERLOAD stuff for
the package Ogre::Animation, not Ogre::Vector3 !

Then :

XS(boot_Ogre); /* prototype to pass -Wmissing-prototypes */
XS(boot_Ogre)
{
dXSARGS;
char* file = __FILE__;

XS_VERSION_BOOTCHECK ;

{
CV * cv ;

/* register the overloading (type 'A') magic */
PL_amagic_generation++;
/* The magic for overload gets a GV* via gv_fetchmeth as */
/* mentioned above, and looks in the SV* slot of it for */
/* the "fallback" status. */
sv_setsv( <---- line 11180
get_sv( "Ogre::Animation::()", TRUE ),
PL_sv_undef
);
/* Making a sub named "Ogre::Animation::()" allows the package */
/* to be findable via fetchmethod(), and causes */
/* overload::Overloaded("Ogre::Animation") to return true. */
newXS("Ogre::Animation::()", XS_Ogre__Animation_nil, file);
cv = newXS("Ogre::TFO_NONE", XS_Ogre_TFO_NONE, file);
XSANY.any_i32 = 0 ;
sv_setpv((SV*)cv, "$") ;


Thinking that it might be due to how I use INCLUDE to drag
in the xs/*.xs files from Ogre.xs,
I put the contents of Vector3.xs into Ogre.xs.
The same error results during `make`,
but this time the class is correctly Ogre::Animation.

I also tried explicit INCLUDEs for every file,
instead of the script that currently INCLUDEs them.

I didn't try putting the content of all xs/*.xs files
into Ogre.xs in order to rule out that it's just
the fact that INCLUDE is used anywhere.
I hope it isn't necessary to put all the XS in one file..
Post by Steve Fink
If anything in the overloaded function is not in your typemap, the
generated C code is completely bogus (syntactically incorrect.)
It's very delicate, XS...
Torsten Schoenfeld
2007-12-30 16:39:29 UTC
Permalink
Post by Scott Lanning
I think it's a bug (or lack of C++ functionality) in xsubpp,
but I'm not ruling out a self-introduced problem. :)
Yep, xsubpp's OVERLOAD support is broken.
Post by Scott Lanning
XS(XS_Ogre__Animation_nil); /* prototype to pass -Wmissing-prototypes */
XS(XS_Ogre__Animation_nil)
{
dXSARGS;
PERL_UNUSED_VAR (items);
Post by Scott Lanning
XSRETURN_EMPTY; <--- line 11158
}
XS(boot_Ogre); /* prototype to pass -Wmissing-prototypes */
XS(boot_Ogre)
{
dXSARGS;
char* file = __FILE__;
XS_VERSION_BOOTCHECK ;
{
CV * cv ;
/* register the overloading (type 'A') magic */
PL_amagic_generation++;
/* The magic for overload gets a GV* via gv_fetchmeth as */
/* mentioned above, and looks in the SV* slot of it for */
/* the "fallback" status. */
sv_setsv( <---- line 11180
get_sv( "Ogre::Animation::()", TRUE ),
PL_sv_undef
&PL_sv_undef
Post by Scott Lanning
);
/* Making a sub named "Ogre::Animation::()" allows the package */
/* to be findable via fetchmethod(), and causes */
/* overload::Overloaded("Ogre::Animation") to return true. */
newXS("Ogre::Animation::()", XS_Ogre__Animation_nil, file);
cv = newXS("Ogre::TFO_NONE", XS_Ogre_TFO_NONE, file);
XSANY.any_i32 = 0 ;
sv_setpv((SV*)cv, "$") ;
Oh, and I just stumbled upon
<http://rt.cpan.org/Public/Bug/Display.html?id=31533> which is about
this problem and which suggests the exact same fixes.

As a workaround, I suggest removing the OVERLOAD stuff from your XS code
and putting something like this in your .pm file:

package Ogre::Animation;

use overload
'==' => sub { \&Ogre::Animation::cmp },
fallback => 1;
--
Bye,
-Torsten
s***@yahoo.com
2008-01-17 22:49:08 UTC
Permalink
Hi
Post by Torsten Schoenfeld
As a workaround, I suggest removing the OVERLOAD stuff from your XS code
package Ogre::Animation;
use overload
'==' => sub { \&Ogre::Animation::cmp },
fallback => 1;
I think you mean...

use overload
'==' => \&Ogre::Animation::cmp,
fallback => 1;


- Salva

Loading...