in reply to Re^4: Including existing C or CPP library using Inline
in thread Including existing C or CPP library using Inline

Thus my guess is that the issue lies with passing Perl strings to a C++

I think it might have more to do with the way that the string has been passed.
For example, cprintit() works fine if you rewrite it as:
int cprintit(const char * seq) { cout << seq << endl; return 10; }
That's how you've passed the strings to do_SSW() - the problem with do_SSW() is that you've specified a *return* of type "string".
Perl's typemapping doesn't handle passing of the "string" type (either as argument or as return). You'll need to provide a typemap for "string" if you want to pass that type around.
What happens if you specify a return type of "char *" (instead of "string") for do_SSW() ?

For a solution using a typemap, this works for me:
#!/usr/bin/perl use warnings; use Inline CPP => Config => BUILD_NOISY => 1, TYPEMAPS => 'C:/_32/pscrpt/inline-cpp/stringtype.map', CLEAN_AFTER_BUILD => 0; use Inline CPP; my $seq = "CTGAGCCGGTAAATC"; my $returned = cprintit($seq); print $returned."\n"; __END__ __CPP__ using namespace std; int cprintit(string seq) { cout << seq << endl; return 10; }
where 'C:/_32/pscrpt/inline-cpp/stringtype.map' contains the following single line (plus newline):
string T_PV
(Safest to provide a fully qualified path to the typemap file - though a path relative to the cwd should also work.)

Cheers,
Rob

Replies are listed 'Best First'.
Re^6: Including existing C or CPP library using Inline
by bontus (Novice) on Mar 23, 2014 at 14:49 UTC
    Hi Rob, This indeed fixed the issue thank you very much! Here's the revised code:
    #!/usr/bin/perl use warnings; use Inline CPP => Config => BUILD_NOISY => 1, CLEAN_AFTER_BUILD => 0, TYPEMAPS => './stringtype.map'; use Inline CPP; my $seq = "CTGAGCCGGTAAATC"; my $ref = "CTGTGCCATGCGACTGGTACAATC"; my $cigar = do_SSW($seq,$ref); print "$cigar\n"; __END__ __CPP__ using namespace std; #include <string> #include "ssw_cpp.h" #include "ssw_cpp.cpp" #include "ssw.c" #include "ssw.h" char *do_SSW(string queryC, string refC) { StripedSmithWaterman::Aligner aligner; StripedSmithWaterman::Filter filter; StripedSmithWaterman::Alignment alignment; aligner.Align(queryC.c_str(), refC.c_str(), refC.size(), filter, & +alignment); string s = alignment.cigar_string.c_str(); char *a = new char[s.size()+1]; a[s.size()] = 0; memcpy(a,s.c_str(),s.size()); return a; }

    Having solved this problem, I am of course facing the next one: since the C++ alignment object contains more information and cannot be fully passed back to Perl right away, I am now trying to find a way to do so. My backup plan is to just concatenate all this information and then split the returned string in Perl.

    Anyhow, again thanks a lot! René

      You can always return an SV* containing a reference to an array, hash, or some complex data structure, if that is more useful.

      Since you're using Inline::CPP, you could also encapsulate the data in a class and provide accessors to each component of the data.


      Dave