String "input/output" parameters in XSUB 
Author Message
 String "input/output" parameters in XSUB

Hi all --

I'm wrapping a C library with XSUBs, and certain functions in this
library like to directly manipulate their string input parameters rather
than strdup() and modify the copies.  (This is mainly for efficiency
reasons, and because it seemed like the natural thing to do in the
context -- these functions always result in a smaller or same-length
string, and usually the caller just wants the result, and doesn't need
to keep its own copy.)

Anyways, there are obviously two ways to wrap a Perl function around
this; either take the more natural (but slightly wasteful) approach:

  $new_str = foo ($old_str);          # preserves $old_str, allocate new
                                      # SV for $new_str

or opt for a literal translation of the C function:

   foo ($old_str);                    # modify $old_str in place, don't
                                      # allocate any new memory

Because it's more natural Perl, I like the first approach -- heck, if
you're that worried about efficiency, just use the C library.  ;-)
However, I'm a bit miffed that my XSUB implementation of the latter is
so much neater.  Here's how I've coded the copy-and-modify version:

SV *
foo (insv)

    SV *    insv

    PREINIT:
       SV *   outsv;
       char * outstr;

    CODE:
       if (! SvOK (insv))
          XSRETURN_UNDEF;
       outsv = newSVsv (insv);
       outstr = SvPV (outsv, na);
       foo (outstr);
       sv_setpv (outsv, outstr);
       RETVAL = outsv;

    OUTPUT:
       RETVAL

I don't like the fact that I'm dealing directly in SVs -- I'd rather
declare char *'s and let the typemap worry about conversion.  And I
really don't like that I have to worry about both the output SV and its
C char * equivalent -- I guess if I was just passing around char *'s
from the start, this wouldn't be a problem.  It also seems to me that
most of this code is boilerplate, but I can't shove it into a C function
because some of that boilerplate does a return, and the rest is cut in
half by calling the C function foo().  I suppose a macro would do it,
but it would be an ugly macro.

Really, I'd like to figure out a way to get this boilerplate done by
XSUB, probably with some help from my typemap.  Any suggestions?

Oh, here's the implementation of the C-like copy-and-modify XSUB:

void
foo (str)

    char * str
    int    options

    CODE:
       if (str != NULL)
          foo (str);
          sv_setpv (ST(0), str);

(My typemap already takes care of turning undef into NULL, hence the NULL
test here.)  So much simpler, nicer, and shorter... but not idiomatic
Perl. :-(

Any suggestions for shortening/simplifying the copy-and-modify version
are welcome!  (Or general critiques of my XSUB style... I'm groping in
the dark here..)

        Greg
--

Corporation for National Research Initiatives    
1895 Preston White Drive                      voice: +1-703-620-8990 x287
Reston, {*filter*}ia, USA  20191-5434               fax: +1-703-620-0913



Wed, 01 Aug 2001 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. <input type="text" value="$string"> problems

2. <input type="text" value="$string"> problems

3. Q: "shift" in subroutine parameters

4. Lists as parameters to "delete"?

5. "use subs" - default parameter

6. Regexp - replace "$string#http://$string#" by "$string"

7. using "Storable" to save program parameters

8. "character class ""bug""

9. Problem with "Stopped (tty input)"

10. problem with <input type="image".....

11. Input type="file"

12. "Unreading" an input line

 

 
Powered by phpBB® Forum Software