Hi All, I am learning how to use XS (C). Firstly, I wrote a simple C++ class, compiled to libtest.so. A simple main proved the test lib works fine. --------------------------------test.h------------------------------- #ifndef _TEST_H #define _TEST_H class Test { public: Test(); ~Test(); void print(void); private: int i; }; #endif ---------------------------------------------------------------------- ----------------------------test.cpp------------------------------- #include "test.h" #include <iostream.h>
Test::Test() { i = 1; cout<<"new inst created"<<endl; } Test::~Test() { cout<<"inst destroyed"<<endl; } void Test::print(void) { cout<<"i = "<< this->i << endl; cout<<"Test::print called"<<endl; } ----------------------------------------------------------------------- Then, I wrote XS stuff and a test perl script(refer to below). The script got a segfault while invoking `delete this' in c++ code. Besides, the initial value of member variable i missed also. -------------- output of `./test.plx ------------------------------- [EMAIL PROTECTED] ~/tmp/Test $ ./test.plx new inst created i = 136090952 Test::print called inst destroyed Segmentation fault ----------------------------------------------------------------------- I checked memleak via valgrind: ------ output of `valgrind --leak-check=yes test.plx' ------ [EMAIL PROTECTED] ~/tmp/Test $ valgrind --leak-check=yes test.plx ==31931== Memcheck, a memory error detector for x86-linux. ==31931== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==31931== Using valgrind-2.4.0, a program supervision framework for x86-linux. ==31931== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==31931== For more details, rerun with: -v ==31931== new inst created i = 464868768 Test::print called inst destroyed ==31931== Invalid free() / delete / delete[] ==31931== at 0x1B905A4E: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x1BEE0229: XS_Test_DESTROY(interpreter*, cv*) (Test.c:52) ==31931== Address 0x1BACBDE4 is 756 bytes inside a block of size 4080 alloc'd ==31931== at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7) ==31931== ==31931== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 41 from 2) ==31931== malloc/free: in use at exit: 753961 bytes in 12648 blocks. ==31931== malloc/free: 24174 allocs, 11527 frees, 1316185 bytes allocated. ==31931== For counts of detected errors, rerun with: -v ==31931== searching for pointers to 12648 not-freed blocks. ==31931== checked 1114300 bytes. ==31931== ==31931== ==31931== 5 bytes in 1 blocks are definitely lost in loss record 2 of 21 ==31931== at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D46CE: Perl_savesharedpv (in /usr/bin/perl5.8.7) ==31931== ==31931== ==31931== 192 bytes in 1 blocks are definitely lost in loss record 11 of 21 ==31931== at 0x1B905DFB: realloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D3424: Perl_safesysrealloc (in /usr/bin/perl5.8.7) ==31931== ==31931== ==31931== 14709 (1991 direct, 12718 indirect) bytes in 14 blocks are definitely lost in loss record 14 of 21 ==31931== at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7) ==31931== ==31931== ==31931== 6160 bytes in 1 blocks are possibly lost in loss record 17 of 21 ==31931== at 0x1B905DFB: realloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D3424: Perl_safesysrealloc (in /usr/bin/perl5.8.7) ==31931== ==31931== ==31931== 181636 bytes in 14 blocks are possibly lost in loss record 20 of 21 ==31931== at 0x1B9052F4: malloc (in /usr/lib/valgrind/vgpreload_memcheck.so) ==31931== by 0x80D3291: Perl_safesysmalloc (in /usr/bin/perl5.8.7) ==31931== ==31931== LEAK SUMMARY: ==31931== definitely lost: 2188 bytes in 16 blocks. ==31931== indirectly lost: 12718 bytes in 80 blocks. ==31931== possibly lost: 187796 bytes in 15 blocks. ==31931== still reachable: 551259 bytes in 12537 blocks. ==31931== suppressed: 0 bytes in 0 blocks. ==31931== Reachable blocks (those to which a pointer was found) are not shown. ==31931== To see them, rerun with: --show-reachable=yes ------------------------------------------------------------------- According to typemap in ExtUtils and perl.h, casting IV to pointer should be safe in this case, since on my machine(32bit, kernel 2.6.12), sizeof(int) == 4, which is the same as a pointer. Does anyone have any idea about this issue? Refer to XS source below: ---------------------- 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() 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 = INT2PTR($type, SvIV($arg)); } else { warn(\"$arg is not a blessed object\"); XSRETURN_UNDEF; } ################ OUTPUT T_OBJECT sv_setref_pv($arg, \"Test\", (void*)$var); --------------------------------------------------------------------- ----------------------Makefiel.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' 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 ); ---------------------------------------------------------------------- -- Bst Rgrs, Dongxu