Hi there, I am learning how to port C++ interface to Perl by perlxs. At first, I wrote a simple C++ class,which has one public method only, compiled as libtest.so. ----------------------------------test.h ------------------------------------------- #ifndef _TEST_H #define _TEST_H class Test { public: Test(); ~Test(); void print(void); }; #endif ---------------------------------------------------------------------------------------- --------------------------------test.cpp---------------------------------------------- #include "test.h" #include <iostream.h> Test::Test() { cout<<"new inst created"<<endl; } Test::~Test() { cout<<"inst destroyed"<<endl; } void Test::print(void) { cout<<"Test::print called"<<endl; } --------------------------------------------------------------------------------------------
Then called `h2xs -A -n Test`, wrote Makefile.PL Test.xs and typemap: ---------------------------------Makefile.PL--------------------------------------------- use 5.008007; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'Test', VERSION_FROM => 'lib/Test.pm', # finds $VERSION PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Test.pm', # retrieve abstract from module AUTHOR => 'A. U. Thor <>') : ()), CC => 'g++', LD => 'g++', LDFLAGS => '-g', LDDLFLAGS => '-shared -g', LIBS => ['-Lclib -ltest'], # e.g., '-lm' libtest.so under subdir clib DEFINE => '', # e.g., '-DHAVE_SOMETHING' INC => '-I.', # e.g., '-I. -I/usr/include/other' XSOPT => ' -C++ ', # Un-comment this if you add C files to link with later: # OBJECT => '$(O_FILES)', # link all the C files too ); ------------------------------------------------------------------------------------------- -------------------------------Test.xs--------------------------------------------------- #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include "clib/test.h" #include "stdio.h" MODULE = Test PACKAGE = Test Test * Test::new() void Test::DESTROY() CODE: delete THIS; fprintf(stdout, "here\n"); NO_OUTPUT void Test::print() CODE: THIS->print(); --------------------------------------------------------------------------------------------- -----------------------------typemap---------------------------------------------------- TYPEMAP Test * T_OBJECT ################ INPUT T_OBJECT if(sv_isa($arg, \"Test\") && sv_isobject($arg)) { $var = ($type)SvIV($arg); } else { warn(\"$arg is not a blessed object\"); XSRETURN_UNDEF; } ################ OUTPUT T_OBJECT sv_setref_pv($arg, \"Test\", (void*)$var); --------------------------------------------------------------------------------------------- After running `perl Makefile.PL` and `make`, I got Test.so Finally, I wrote a test script: ---------------------test.plx--------------------------------------------------------------- #! /usr/bin/perl use warnings; use strict; use blib q(blib); use Test (); my $inst = Test::->new(); $inst->print(); undef $inst; ---------------------------------------------------------------------------------------------- ran it in shell I got: -----------------------output of `test.plx`------------------------------------------------- [EMAIL PROTECTED] ~/tmp/Test $ ./test.plx new inst created Test::print called inst destroyed Segmentation fault [EMAIL PROTECTED] ~/tmp/Test $ ---------------------------------------------------------------------------------------------- while running the same script in perldb, I got: -------------------output of `perl -d -MDevel::Peek test.plx` ------------------------ Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(test.plx:9): my $inst = Test::->new(); DB<1> n new inst created main::(test.plx:10): $inst->print(); DB<1> Dump $inst SV = PVMG(0x844b680) at 0x81aea98 REFCNT = 2 FLAGS = (PADBUSY,PADMY,ROK) IV = 0 NV = 0 RV = 0x852a01c SV = PVMG(0x844b700) at 0x852a01c REFCNT = 1 FLAGS = (OBJECT,IOK,pIOK) IV = 135961544 NV = 0 PV = 0 STASH = 0x8416f74 "Test" PV = 0x852a01c "" CUR = 0 LEN = 0 DB<2> s Test::print called main::(test.plx:12): undef $inst; DB<2> s inst destroyed here Debugged program terminated. Use q to quit or R to restart, use O inhibit_exit to avoid stopping after program termination, h q, h R or h O to get additional info. DB<2> ------------------------------------------------------------------------------------------- As seen, in debug mode, "DELETE THIS;", which calls Test::~Test() in c++ code, returned successfully. While in normal shell, it caused a segfault. Is there any error in my code above? Does anyone know the reason? Thanks in advance. -- Bst Rgrs, Dongxu