bontus has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

My current task involves string alignments, for which I found a very promising C/C++ library that I would like to call from my Perl code. The library can be found here: https://github.com/mengyao/Complete-Striped-Smith-Waterman-Library

and an example for C++ usage can be found here:

https://github.com/mengyao/Complete-Striped-Smith-Waterman-Library/blob/master/src/example.cpp

What I had in mind is, to create either a subroutine or a separate module that passes the sequences (query and ref in the example) to the C function. Several variables can then store the returned results. Unfortunately, I do not even get the first part running with only one variable being returned (disclaimer: I am not a C programmer and Inline sounds cool, but is also new to me).

Based on the C++ package, I wrote the following piece to get a general understanding of what is going on, which results in "Undefined subroutine &main::do_SSW called at ./somePerl.pl line 8.". FYI, the CIGAR string is a compact format to display alignments, see:

http://genome.sph.umich.edu/wiki/SAM#What_is_a_CIGAR.3F

Many thanks in advance, any help is greatly appreciated.
#!/usr/bin/perl use warnings; use Inline CPP => Config => AUTO_INCLUDE => '#include "ssw_cpp.h"'; my $ref = "CAGCCTTTCTGACCCGGAAATCAAAATAGGCACAACAAA"; my $seq = "CTGAGCCGGTAAATC"; my $cigar = do_SSW($seq,$ref); print "$cigar\n"; __END__ __CPP__ static string do_SSW(const string query, const string ref) { StripedSmithWaterman::Aligner aligner; StripedSmithWaterman::Filter filter; StripedSmithWaterman::Alignment alignment; aligner.Align(query.c_str(), ref.c_str(), ref.size(), filter, &ali +gnment); return alignment.cigar_string; }

Replies are listed 'Best First'.
Re: Including existing C or CPP library using Inline
by syphilis (Archbishop) on Mar 11, 2014 at 22:38 UTC
    Undefined subroutine &main::do_SSW

    You've provided some Inline::CPP config directives, but haven't really done anything to invoke Inline::CPP.
    Hence the whole script gets parsed as a purely perl script ... and perl's parsing doesn't see any do_SSW sub.

    Immediately following the use Inline CPP => .... line, insert the line:
    use Inline CPP;
    That will at least invoke Inline::CPP.
    There may well be other problems - eg I expect that you will need to link to the cpp library (in the Config directives):
    LIBS => '-L/your/lib/path -lyourlib',
    Update: It would also be a good idea to stick:a
    BUILD_NOISY => 1,
    in the Config section.

    Cheers,
    Rob

      Dear Rob,

      I followed your advise and including  use Inline CPP; did help. Now, I am still struggling with passing perl strings to the function itself, which I guess is the reason for the function not being found. I wrote another function that is supposed to just print the passed string via cout and I also get the subroutine not found error. Integers work fine though, so it seems that converting the perl strings to C++ strings needs some work around.

      Best, René
        I wrote another function that is supposed to just print the passed string via cout and I also get the subroutine not found error

        It's hard to be certain without seeing the code, but it sounds like Inline might be unable to bind to the function.
        Rather than having anything to do with the arguments being passed, this would more likely be due to an unrecognised type being returned by the function.

        We really need to see the code you've tried, along with the error messages you're getting in order to be of much assistance.

        Cheers,
        Rob