Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re: Passing a very large string by reference to a c library

by jeroenes (Priest)
on Jul 12, 2001 at 16:49 UTC ( [id://96012]=note: print w/replies, xml ) Need Help??


in reply to Passing a very large string by reference to a c library

Here you have a snippet:
SV * _smooth2( yp, wp, lambda_in, m ) char * yp char * wp SV * lambda_in int m CODE: { int i, i1, i2, ip; double c[MMAX+1], d[MMAX+1], e[MMAX+1], w[MMAX+1], y[MMAX+1], z[MMAX+1], lambda; double * ya; double * wa; ya = (double *) yp; wa = (double *) wp;
You see, the c uses pointers to address the strings. Char is the default type, you need to convert inside the code.

From perl, I call:

Smooth::_smooth2( $py, $pw, $lambda, scalar( @$yref ) );
Where the $py and $pw are strings. XS automagically builds the pointers for you.

Hope this helps,

Jeroen
"We are not alone"(FZ)
Update: Because the c-code sees only the pointers, no copy is made. To be sure, I tested it with a fresh module: TestMemXS:

#XS #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "unistd.h" MODULE = TestMemXS PACKAGE = TestMemXS void _test( yp ) char * yp CODE: { double * ya; ya = (double *) yp; sleep( 1000 ); } ------------------- #testMemXS.pm .... sub testMem{ my $str = "\000" x 50e6; _test( $str ); } .... ------------------- perl -MTestMemXS -e 'testMem()'
The perl process didn't exceed 55M...

Replies are listed 'Best First'.
Re: Re: Passing a very large string by reference to a c library
by dino (Sexton) on Jul 16, 2001 at 15:22 UTC
    This stems from my (mistaken) belief that perl copies variables on subroutine calls. It appears that this is not true ;-). It seems that the copying may take place during the standard assignment in the subroutine body which can be avoided with a little thought. eg:
    
    &find_index($key, \$bigstring);
    
    sub find_index {
      my ($key, $rbigstring) = @_;
    
    becomes:
    &find_index($key, $bigstring);
    
    sub find_index {
      my ($key) = $_[0];
      my ($rbigstring) = \$_[1];
     

    This has the added benefit of making the sub call for both c and perl the same.

    Thanks for your help

    dino

Re: Re: Passing a very large string by reference to a c library
by dino (Sexton) on Jul 12, 2001 at 17:02 UTC
    Mmm thanks,

    but if $pw is 50M in size then by not passing it as a ref, do the perl api routines convert it to a char * on every call?

    dino

      Perl does "pass by reference" already. No need to complicate things by taking a reference and passing that "by reference". So the above code does no copying and is really the simplest method.

              - tye (but my friends call me "Tye")

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-20 13:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found