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
>
>

Reply via email to