Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^3: Including existing C or CPP library using Inline

by syphilis (Archbishop)
on Mar 12, 2014 at 23:30 UTC ( [id://1078107]=note: print w/replies, xml ) Need Help??


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

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
  • Comment on Re^3: Including existing C or CPP library using Inline

Replies are listed 'Best First'.
Re^4: Including existing C or CPP library using Inline
by bontus (Novice) on Mar 21, 2014 at 18:24 UTC
    Hi Rob,

    Here's the code I mentioned in my previous post. The 'add' function works properly if I execute it, whereas calling 'doSSW' results in a "Undefined subroutine" error. Thus my guess is that the issue lies with passing Perl strings to a C++ function.

    Best, René
    #!/usr/bin/perl use warnings; use Inline CPP => Config => BUILD_NOISY => 1, CLEAN_AFTER_BUILD => 0; use Inline CPP => Config => AUTO_INCLUDE => '#include "ssw_cpp.h"'; use Inline CPP; my $ref = "CAGCCTTTCTGACCCGGAAATCAAAATAGGCACAACAAA"; my $seq = "CTGAGCCGGTAAATC"; print add(3,5)."\n"; my $returned = cprintit($seq); print $returned."\n"; #my $cigar = do_SSW($seq,$ref); #print "$cigar\n"; __END__ __CPP__ using namespace std; string do_SSW(const char* queryC, const char* refC) { Inline_Stack_Vars; string query(queryC); string ref(refC); 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; } int add (const int a, const int b) { int c = a+b; return c; } int cprintit(const string seq) { cout << seq << endl; return 10; }
      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
        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é

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1078107]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2024-04-19 06:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found