Hi to all XS experts,
I face a strange pb while compiling my XS module, and really need some
support/help/advice to solve it.

I'm running Ubuntu 8.04 Hardy, kernel 2.6.24-19-generic
My Perl is v5.8.8 built for i486-linux-gnu-thread-multi
My compiler is g++ (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)
My C+ STL is libstdc++6-4.2-dev version 4.2.3-2ubuntu7

I have written a C++ library to handle mutiplexing/demultiplexing of
digital video streams. Its name is libmosmux.
The library works fine as long as I stay in the C++ world.
I can compile it, and can link it to C++ executable. The resulting
executables do run without any pb.

Now I want to wrap that library in a Perl XS module named MosMux.pm
I have written a Makefile.PL, the MosMux.pm module and the MosMux.xs
file as explained in the tutorials I have read.
there are also a ppport.h and a typemap files.

When I finally launch "make", I got the following messages:

$ make
cp lib/MOS/MosMux.pm blib/lib/MOS/MosMux.pm
AutoSplitting blib/lib/MOS/MosMux.pm (blib/lib/auto/MosMux)
/usr/bin/perl /usr/share/perl5/ExtUtils/xsubpp  -C++
-typemap /usr/share/perl/5.8/ExtUtils/typemap -typemap typemap -typemap
typemap  MosMux.xs > MosMux.xsc && mv MosMux.xsc MosMux.c
Please specify prototyping behavior for MosMux.xs (see perlxs manual)
g++ -c  -I. -I../../libmosmux -I../../DTAPI/Include -D_REENTRANT
-D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2
-DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC
"-I/usr/lib/perl/5.8/CORE"   MosMux.c
In file included from MosMux.xs:14:
./../../libmosmux/libmosmux.h:136:1: warning: "VERSION" redefined
<command-line>: warning: this is the location of the previous definition
In file included from /usr/include/c++/4.2/bits/basic_ios.h:44,
                 from /usr/include/c++/4.2/ios:50,
                 from /usr/include/c++/4.2/istream:44,
                 from /usr/include/c++/4.2/fstream:45,
                 from ./../../libmosmux/libmosmux.h:228,
                 from MosMux.xs:14:
/usr/include/c++/4.2/bits/locale_facets.h:4420:40: error: macro
"do_open" requires 7 arguments, but only 2 given
/usr/include/c++/4.2/bits/locale_facets.h:4467:34: error: macro
"do_close" requires 2 arguments, but only 1 given
/usr/include/c++/4.2/bits/locale_facets.h:4486:55: error: macro
"do_open" requires 7 arguments, but only 2 given
/usr/include/c++/4.2/bits/locale_facets.h:4513:23: error: macro
"do_close" requires 2 arguments, but only 1 given
In file included from /usr/include/c++/4.2/bits/locale_facets.h:4599,
                 from /usr/include/c++/4.2/bits/basic_ios.h:44,
                 from /usr/include/c++/4.2/ios:50,
                 from /usr/include/c++/4.2/istream:44,
                 from /usr/include/c++/4.2/fstream:45,
                 from ./../../libmosmux/libmosmux.h:228,
                 from MosMux.xs:14:
/usr/include/c++/4.2/i486-linux-gnu/bits/messages_members.h:70:38:
error: macro "do_open" requires 7 arguments, but only 2 given
/usr/include/c++/4.2/i486-linux-gnu/bits/messages_members.h:85:23:
error: macro "do_open" requires 7 arguments, but only 2 given
/usr/include/c++/4.2/i486-linux-gnu/bits/messages_members.h:95:39:
error: macro "do_close" requires 2 arguments, but only 1 given
In file included from /usr/include/c++/4.2/bits/basic_ios.h:44,
                 from /usr/include/c++/4.2/ios:50,
                 from /usr/include/c++/4.2/istream:44,
                 from /usr/include/c++/4.2/fstream:45,
                 from ./../../libmosmux/libmosmux.h:228,
                 from MosMux.xs:14:
/usr/include/c++/4.2/bits/locale_facets.h:4486: error: ‘do_open’
declared as a ‘virtual’ field
/usr/include/c++/4.2/bits/locale_facets.h:4486: error: expected ‘;’
before ‘const’
/usr/include/c++/4.2/bits/locale_facets.h:4513: error: variable or field
‘do_close’ declared void
/usr/include/c++/4.2/bits/locale_facets.h:4513: error: expected ‘;’
before ‘const’
In file included from /usr/include/c++/4.2/bits/locale_facets.h:4599,
                 from /usr/include/c++/4.2/bits/basic_ios.h:44,
                 from /usr/include/c++/4.2/ios:50,
                 from /usr/include/c++/4.2/istream:44,
                 from /usr/include/c++/4.2/fstream:45,
                 from ./../../libmosmux/libmosmux.h:228,
                 from MosMux.xs:14:
/usr/include/c++/4.2/i486-linux-gnu/bits/messages_members.h:84: error:
expected initializer before ‘const’
/usr/include/c++/4.2/i486-linux-gnu/bits/messages_members.h:95: error:
expected initializer before ‘const’
MosMux.c: In function ‘void boot_MOS__MosMux(PerlInterpreter*, CV*)’:
MosMux.c:257: warning: deprecated conversion from string constant to
‘char*’
MosMux.c:263: warning: deprecated conversion from string constant to
‘char*’
MosMux.c:264: warning: deprecated conversion from string constant to
‘char*’
MosMux.c:265: warning: deprecated conversion from string constant to
‘char*’
MosMux.c:266: warning: deprecated conversion from string constant to
‘char*’
make: *** [MosMux.o] Error 1
                                                                                
        


Forget about the warnings for deprecated conversion. I have to fix it,
but it's not the point.

The real pb are the various errors occuring from included files from the
STL lib.
I don't understand why I got these errors when compiling the XS module
while I don't have any when compiling the C++ libmosmux library.

I'd really appreciate any hint that could lead me to the light..

Thanks in advance

Christophe
[EMAIL PROTECTED]




Here are the various files mentioned:

Makefile.PL
============
use 5.008008;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
$CC = 'g++';

WriteMakefile(
    NAME              => 'MOS::MosMux',
    VERSION_FROM        => 'lib/MOS/MosMux.pm',
    PREREQ_PM => {
        'Test::More' => 0,
    },
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/MOS/MosMux.pm', # retrieve abstract from
module
       AUTHOR         => 'Christophe Massaloux
<[EMAIL PROTECTED]>') : ()),
    LIBS              => [''], # e.g., '-lm'
    DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
    INC               => '-I. -I../../libmosmux -I../../DTAPI/Include',
# e.g., '-I. -I/usr/include/other'
    'CC'                => $CC,
    'LD'                => '$(CC)',
    XSOPT             => '-C++',
    TYPEMAPS          => ['typemap'],
    MYEXTLIB          => '../../libmosmux/libmosmux$(LIB_EXT)',
        # Un-comment this if you add C files to link with later:
    OBJECT            => '$(O_FILES)', # link all the C files too
    dist                => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
    clean               => { FILES => 'MOS-MosMux-*' },
);

if  (eval {require ExtUtils::Constant; 1}) {
  # If you edit these definitions to change the constants used by this
module,
  # you will need to use the generated const-c.inc and const-xs.inc
  # files to replace their "fallback" counterparts before distributing
your
  # changes.
  my @names = (qw());
  ExtUtils::Constant::WriteConstants(
                                     NAME         => 'MosMux',
                                     NAMES        => [EMAIL PROTECTED],
                                     DEFAULT_TYPE => 'IV',
                                     C_FILE       => 'const-c.inc',
                                     XS_FILE      => 'const-xs.inc',
                                  );

}
else {
  use File::Copy;
  use File::Spec;
  foreach my $file ('const-c.inc', 'const-xs.inc') {
    my $fallback = File::Spec->catfile('fallback', $file);
    copy ($fallback, $file) or die "Can't copy $fallback to $file: $!";
  }
}

sub MY::postamble {
'
$(MYEXTLIB): ../../libmosmux/Makefile
        cd ../../libmosmux && $(MAKE) $(PASSTHRU)
';
}


MosMux.pm:
==========
package MosMux;
use 5.008008;
use strict;
use warnings;
use Carp;
require Exporter;
use AutoLoader;

our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw() ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = '0.01';
sub AUTOLOAD {
    my $constname;
    our $AUTOLOAD;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "&MosMux::constant not defined" if $constname eq 'constant';
    my ($error, $val) = constant($constname);
    if ($error) { croak $error; }
    {
        no strict 'refs';
        # Fixed between 5.005_53 and 5.005_61
#XXX    if ($] >= 5.00561) {
#XXX        *$AUTOLOAD = sub () { $val };
#XXX    }
#XXX    else {
            *$AUTOLOAD = sub { $val };
#XXX    }
    }
    goto &$AUTOLOAD;
}

require XSLoader;
XSLoader::load('MosMux', $VERSION);

1;



MosMux.xs:
Note: the "sectionRead" class is just a wrapper for the needed features
of the lib
==========
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "const-c.inc"
#ifdef __cplusplus
}
#endif

#undef list
#include <../../libmosmux/libmosmux.h>

using namespace std;
using namespace mosmux;

class sectionRead
{
    private:
        MosMuxMultiplexer*  m_mux;
        MosMuxSaver*        m_saver;
        MosMuxOutput*       m_out;

    public:
        sectionRead(int BitRateIn, char* inputTSFileName, int pid, int
tid, bool hasLSN, bool hasCRC32) {
            MosMuxInput* in1 = new MosMuxTSFileInput( BitRateIn,
inputTSFileName );
            m_out = new MosMuxMonoSectionStringOutput(BitRateIn, pid,
tid, hasLSN, hasCRC32, 2);
            m_saver =
((MosMuxSectionExporter*)(m_out->getExporter()))->getSaver();
            m_mux = new MosMuxMultiplexer();
            m_mux->addInput(in1);
            m_mux->addOutput(m_out);
            m_mux->start();
        }
        ~sectionRead(){}

        std::string read() {
            m_mux->run();
            m_out->flush();
            std::string section =
((MosMuxSaver2String*)(m_saver))->getSectionsString();
            ((MosMuxSaver2String*)(m_saver))->clearSectionsString();
            return section;
        }
};


MODULE = MOS::MosMux            PACKAGE = MOS::MosMux           

INCLUDE: const-xs.inc

sectionRead *
sectionRead::new(BitRateIn, inputTSFileName, pid, tid, hasLSN, hasCRC32)
        int    BitRateIn
        char*  inputTSFileName
        int    pid
        int    tid
        bool   hasLSN
        bool   hasCRC32

void
sectionRead::DESTROY()

SV *
sectionRead::read()
INIT:
        std::string retstring;
CODE:
        retstring = THIS->read();
        RETVAL = newSVpvn(retstring.c_str(), retstring.size());
OUTPUT:
        RETVAL



typemap:
========
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "const-c.inc"
#ifdef __cplusplus
}
#endif

#undef list
#include <../../libmosmux/libmosmux.h>

using namespace std;
using namespace mosmux;

class sectionRead
{
    private:
        MosMuxMultiplexer*  m_mux;
        MosMuxSaver*        m_saver;
        MosMuxOutput*       m_out;

    public:
        sectionRead(int BitRateIn, char* inputTSFileName, int pid, int
tid, bool hasLSN, bool hasCRC32) {
            MosMuxInput* in1 = new MosMuxTSFileInput( BitRateIn,
inputTSFileName );
            m_out = new MosMuxMonoSectionStringOutput(BitRateIn, pid,
tid, hasLSN, hasCRC32, 2);
            m_saver =
((MosMuxSectionExporter*)(m_out->getExporter()))->getSaver();
            m_mux = new MosMuxMultiplexer();
            m_mux->addInput(in1);
            m_mux->addOutput(m_out);
            m_mux->start();
        }
        ~sectionRead(){}

        std::string read() {
            m_mux->run();
            m_out->flush();
            std::string section =
((MosMuxSaver2String*)(m_saver))->getSectionsString();
            ((MosMuxSaver2String*)(m_saver))->clearSectionsString();
            return section;
        }
};


MODULE = MOS::MosMux            PACKAGE = MOS::MosMux           

INCLUDE: const-xs.inc

sectionRead *
sectionRead::new(BitRateIn, inputTSFileName, pid, tid, hasLSN, hasCRC32)
        int    BitRateIn
        char*  inputTSFileName
        int    pid
        int    tid
        bool   hasLSN
        bool   hasCRC32

void
sectionRead::DESTROY()

SV *
sectionRead::read()
INIT:
        std::string retstring;
CODE:
        retstring = THIS->read();
        RETVAL = newSVpvn(retstring.c_str(), retstring.size());
OUTPUT:
        RETVAL





Reply via email to