Discussion:
C++
(too old to reply)
Philip M. Gollucci
2006-11-11 10:08:29 UTC
Permalink
Before tackling a larger project, I am trying to get a little demo C++
fraction class (attached) bound with XS.
It compiles properly but fails make test with a
make: *** [test_dynamic] Segmentation fault
The problem seems to be passing the result of the fract::operator+
function back to Perl.
Thanks for any help!
#line 76 "Fract.xs"
// fract *ptr1,*ptr2,*ptr;
// ptr=new fract;
RETVAL->operator=(*THIS+*other);

RETVAL is not yet initialized yet its simply a pointer if you look at
the Fract.c file.
diff Fract.xs Fract.xs.new
--- Fract.xs Sat Nov 11 02:08:04 2006
+++ Fract.xs.new Sat Nov 11 02:08:00 2006
@@ -75,6 +75,7 @@
CODE:
// fract *ptr1,*ptr2,*ptr;
// ptr=new fract;
+ RETVAL = new fract();
RETVAL->operator=(*THIS+*other);
cerr << "RetVal calculated...\n";
// RETVAL=Data_Wrap_Struct(cFract,0,fract::free,ptr);


HTH
--
------------------------------------------------------------------------
Philip M. Gollucci (***@p6m7g8.com) 323.219.4708
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Software Engineer - TicketMaster - http://ticketmaster.com
1024D/A79997FA F357 0FDD 2301 6296 690F 6A47 D55A 7172 A799 97F

I never had a dream come true
'Til the day that I found you.
Even though I pretend that I've moved on
You'll always be my baby.
I never found the words to say
You're the one I think about each day
And I know no matter where life takes me to
A part of me will always be...
A part of me will always be with you.
Jeffrey Ratcliffe
2006-11-13 07:56:14 UTC
Permalink
Thanks for taking your time to help.
Post by Philip M. Gollucci
RETVAL is not yet initialized yet its simply a pointer if you look at
the Fract.c file.
Thanks. Sometimes, you just can't see the wood for the trees.

Another question:

There are three forms of the C++ new() function, depending on whether
you are providing a numerator and denominator as initialisation,
another fraction, or nothing. Can I wrap all three with one function,
or do I have to create three Perl functions?

Regards

Jeff
Nicholas Clark
2006-11-13 11:47:36 UTC
Permalink
Post by Jeffrey Ratcliffe
There are three forms of the C++ new() function, depending on whether
you are providing a numerator and denominator as initialisation,
another fraction, or nothing. Can I wrap all three with one function,
or do I have to create three Perl functions?
Yes, but you'll have to put in explicit logic to decide which C++ new to use
inside your XS code. I'm unaware of any way to automatically wrap overloaded
functions.

Nicholas Clark
Jeffrey Ratcliffe
2006-11-13 13:02:35 UTC
Permalink
Post by Nicholas Clark
Post by Jeffrey Ratcliffe
There are three forms of the C++ new() function, depending on whether
you are providing a numerator and denominator as initialisation,
another fraction, or nothing. Can I wrap all three with one function,
or do I have to create three Perl functions?
Yes, but you'll have to put in explicit logic to decide which C++ new to use
inside your XS code. I'm unaware of any way to automatically wrap overloaded
functions.
OK. I've tried to do this and have got two problems. The first is
casting, I'm getting with the XS fragment listed below:

Fract.xs:45: error: no matching function for call to `fract::fract(fract*&)'
fract.h:17: note: candidates are: fract::fract(long int, long int)
fract.h:16: note: fract::fract(const fract&)
fract.h:15: note: fract::fract()

I've obviously got something not quite right with the

arg = (fract *)SvIV((SV*)SvRV( arg1 ));

line. Any idea what it is?

Secondly, I can't seem to make the arguments optional. Despite the

PROTOTYPE: ;$$

line, the c code produces still starts:

if (items != 3)
Perl_croak(aTHX_ "Usage: Fract::new(CLASS, arg1, arg2)");
{

I'd be grateful for any ideas.

Thanks

Jeff

XS fragment:

fract *
fract::new(arg1, arg2)
SV * arg1
SV * arg2
PROTOTYPE: ;$$
CODE:
if (items == 3) {
RETVAL = new fract(SvIV(arg1), SvIV(arg2));
}
else if (items == 2) {
fract * arg;
arg = (fract *)SvIV((SV*)SvRV( arg1 ));
RETVAL = new fract(arg);
}
else if (items == 1) {
RETVAL = new fract;
}
OUTPUT:
RETVAL
Jeffrey Ratcliffe
2006-11-15 06:21:13 UTC
Permalink
Anybody?
Post by Jeffrey Ratcliffe
Post by Nicholas Clark
Post by Jeffrey Ratcliffe
There are three forms of the C++ new() function, depending on whether
you are providing a numerator and denominator as initialisation,
another fraction, or nothing. Can I wrap all three with one function,
or do I have to create three Perl functions?
Yes, but you'll have to put in explicit logic to decide which C++ new to use
inside your XS code. I'm unaware of any way to automatically wrap overloaded
functions.
OK. I've tried to do this and have got two problems. The first is
Fract.xs:45: error: no matching function for call to `fract::fract(fract*&)'
fract.h:17: note: candidates are: fract::fract(long int, long int)
fract.h:16: note: fract::fract(const fract&)
fract.h:15: note: fract::fract()
I've obviously got something not quite right with the
arg = (fract *)SvIV((SV*)SvRV( arg1 ));
line. Any idea what it is?
Secondly, I can't seem to make the arguments optional. Despite the
PROTOTYPE: ;$$
if (items != 3)
Perl_croak(aTHX_ "Usage: Fract::new(CLASS, arg1, arg2)");
{
I'd be grateful for any ideas.
Thanks
Jeff
fract *
fract::new(arg1, arg2)
SV * arg1
SV * arg2
PROTOTYPE: ;$$
if (items == 3) {
RETVAL = new fract(SvIV(arg1), SvIV(arg2));
}
else if (items == 2) {
fract * arg;
arg = (fract *)SvIV((SV*)SvRV( arg1 ));
RETVAL = new fract(arg);
}
else if (items == 1) {
RETVAL = new fract;
}
RETVAL
Jeffrey Ratcliffe
2006-11-15 09:38:36 UTC
Permalink
I don't know about the casting problem, but that line needs to be
fract::new(arg1, arg2, ...)
in order to get optional arguments.
Ah. Excellent. Thank you.

And I figured out the casting problem too. It was staring me in the face:

fract *
fract::new(...)
CODE:
if (items == 3) {
RETVAL = new fract(SvIV( ST(1) ), SvIV( ST(2) ));
}
else if (items == 2) {
fract * arg;
arg = (fract *)SvIV((SV*)SvRV( ST(1) ));
RETVAL = new fract(*arg);
}
else if (items == 1) {
RETVAL = new fract;
}
OUTPUT:
RETVAL

Jeffrey Ratcliffe
2006-11-15 06:21:54 UTC
Permalink
Anybody?
Post by Jeffrey Ratcliffe
Post by Nicholas Clark
Post by Jeffrey Ratcliffe
There are three forms of the C++ new() function, depending on whether
you are providing a numerator and denominator as initialisation,
another fraction, or nothing. Can I wrap all three with one function,
or do I have to create three Perl functions?
Yes, but you'll have to put in explicit logic to decide which C++ new to use
inside your XS code. I'm unaware of any way to automatically wrap overloaded
functions.
OK. I've tried to do this and have got two problems. The first is
Fract.xs:45: error: no matching function for call to `fract::fract(fract*&)'
fract.h:17: note: candidates are: fract::fract(long int, long int)
fract.h:16: note: fract::fract(const fract&)
fract.h:15: note: fract::fract()
I've obviously got something not quite right with the
arg = (fract *)SvIV((SV*)SvRV( arg1 ));
line. Any idea what it is?
Secondly, I can't seem to make the arguments optional. Despite the
PROTOTYPE: ;$$
if (items != 3)
Perl_croak(aTHX_ "Usage: Fract::new(CLASS, arg1, arg2)");
{
I'd be grateful for any ideas.
Thanks
Jeff
fract *
fract::new(arg1, arg2)
SV * arg1
SV * arg2
PROTOTYPE: ;$$
if (items == 3) {
RETVAL = new fract(SvIV(arg1), SvIV(arg2));
}
else if (items == 2) {
fract * arg;
arg = (fract *)SvIV((SV*)SvRV( arg1 ));
RETVAL = new fract(arg);
}
else if (items == 1) {
RETVAL = new fract;
}
RETVAL
Loading...