Steffen, Thanks, I've tried your ExtUtils::XSpp, however I seem to be having the same problem. I've modified the included Object-WithIntAndString example to include a child method, below is the patch:
diff -Naur ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/IntAndString.cc ./IntAndString.cc --- ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/IntAndString.cc 2011-03-12 17:26:28.000000000 +0800 +++ ./IntAndString.cc 2011-04-10 10:04:00.292399419 +0800 @@ -28,3 +28,7 @@ fString = string(arg); } +IntAndString *IntAndString::child() { + return new IntAndString("chidl", 5); +} + diff -Naur ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/IntAndString.h ./IntAndString.h --- ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/IntAndString.h 2011-03-12 17:26:28.000000000 +0800 +++ ./IntAndString.h 2011-04-10 09:57:51.300387585 +0800 @@ -3,6 +3,8 @@ #include <string> +class IntAndString; + class IntAndString { public: IntAndString(); @@ -15,6 +17,8 @@ void SetValue(int arg); void SetValue(const char* arg); + IntAndString *child(); + private: std::string fString; diff -Naur ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/Object-WithIntAndString.xsp ./Object-WithIntAndString.xsp --- ../../../a/ExtUtils-XSpp-0.1601/examples/Object-WithIntAndString/Object-WithIntAndString.xsp 2011-03-12 17:26:28.000000000 +0800 +++ ./Object-WithIntAndString.xsp 2011-04-10 09:59:33.685003371 +0800 @@ -19,6 +19,8 @@ int GetInt(); const char* GetString (); + IntAndString *child(); + // SetValue is polymorphic. We want separate methods in Perl %name{SetString} void SetValue( const char* arg = NULL ); %name{SetInt} void SetValue( int arg ); When I compile, I get the same error: WithIntAndString.c: In function ‘void XS_Object__WithIntAndString_child(PerlInterpreter*, CV*)’: WithIntAndString.c:292: error: ‘CLASS’ was not declared in this scope make: *** [WithIntAndString.o] Error 1 It seems I will need to spend some time to understand XS and perl guts. I was just hoping to add a perl interface without spending to much time.. Cheers James On 10 April 2011 01:08, Steffen Mueller <smuel...@cpan.org> wrote: > Hi James, > > while I have a fair amount of experience with wrapping C++ using XS, it's > one of those things I have to relearn almost every time I use it. > > > On 04/09/2011 08:25 AM, James Shirley wrote: > >> Hi, I'm trying to write a XS routine to return a point to a c++ class to >> be accessible from perl.. >> >> I'm new to XS, so i've been following: >> >> http://www.johnkeiser.com/perl-xs-c++.html >> >> and >> >> http://search.cpan.org/~dmr/CookBookB-19960430/ >> > > If you're interested in a different approach, have a look at ExtUtils::XSpp > (and possibly Module::Build::With::WithXSpp) and the slides from my talk at > YAPC::EU in Pisa, 2010: http://steffen-mueller.net/talks/xspp/ > > ExtUtils::XSpp generates XS for wrapping C++. That means you can even look > at the generated XS to steal from it. > > > However when I try make the xs generated code, i get the following >> compiler error: >> >> g++ -c -I. -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing >> -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE >> -D_FILE_OFFSET_BITS=64 -O2 -g -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" >> -fPIC "-I/usr/lib/perl/5.10/CORE" MyPackage.c >> MyPackage.c: In function ‘void XS_MyPackage_child(PerlInterpreter*, CV*)’: >> MyPackage.c:168: error: ‘CLASS’ was not declared in this scope >> make: *** [MyPackage.o] Error 1 >> >> I assume I'm doing something wrong in the child method, however i lifted >> this code out of one of the CookBookB examples.. >> >> MyClass * >> MyClass::child() >> CODE: >> RETVAL = (MyClass *)safemalloc( sizeof(MyClass) ); >> *RETVAL = THIS->child(); >> > > > Hmm. Generally, look at the C(++) code that is generated by xsubpp. In a > lot of cases, it is more instructive for debugging than XS. > > In this case, I bet that your typemap for O_OBJECT uses the CLASS (C) > variable for finding the Perl class name to bless the new object into. The > code for setting CLASS is generated by xsubpp/ExtUtils::ParseXS. > Unfortunately, there's some special case logic for new() methods. Quoting > from the newest EU::ParseXS: > > my $arg0 = ((defined($static) or $func_name eq 'new') > ? "CLASS" : "THIS"); > > Yikes. A better solution for the preprocessor would be to have an XS > attribute/decorator that indicates "this requires CLASS to be set" and/or > "this is a constructor" or whatever. Hmm, it's actually something that > should be part of the typemap. "Please set CLASS for this typemap". One can > dream. But I'll certainly push this on top of the stack of things to look > into wrt. rethinking how typemaps work at the upcoming QA hackathon. Any > input would be welcome on this. > > Getting back to your problem: You could work around this by creating a new > Perl object manually in your XS wrapper (with the known class name) and > pushing it on the stack manually, too. In that case, set the return type of > your XSUB to void. This is what your typemap normally does for you, so you > can take the code from there. It probably involves at least the XPUSHs macro > and likely either sv_bless or sv_setref_iv or another sv_setref_* macro. See > perlapi.pod. > > Best regards, > Steffen > >