Re: XS C++ return class pointers

[email protected] (James Shirley)
Newsgroups perl.xs
Message-ID <[email protected]>
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 <[email protected]> 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
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.