in reply to Re: Perl extension parameters (by ref)
in thread Perl extension parameters

Thank you, Tye. I'd gone through passing by reference and struggled with it for a week before I saw the documentation from perlxs and gave up thinking that there was an easier way (I was wrong). The thing that hung me up, and actually still bothers me is that the Perl script is passing a value, and the corresponding C code parameter is a pointer. We dereference the pointer and change the value in the space to which it is pointing, and when we get back to the Perl script, the parameter is a value again. To me this is counter intuitive. I would think that you would pass a reference from Perl and that would translate into a C pointer. Could you un-confuse me on this point? Thanks again for your help!!!
  • Comment on Re: Re: Perl extension parameters (by ref)

Replies are listed 'Best First'.
Re^3: Perl extension parameters (by ref)
by tye (Sage) on Mar 09, 2004 at 08:01 UTC

    Arguments to Perl subroutines are passed by alias. That is a lot like 'pass by reference' but not quite exactly and the word 'reference' in 'pass by reference' is only a bit related to the word 'reference' in 'Perl reference'.

    The "OUTPUT:" tells the XS code to do the equivalent of $_[0] = .... No need to pass in a reference. For regular Perl subroutines, it is often a good idea to use references rather than relying on 'pass by alias' (it often leads to clearer code), but for XS subroutines it would mostly add complication and more places to introduce bugs.

    A Perl reference wouldn't translate into a C pointer, at least not an 'int *'. It'd give you a pointer to a perl struct (RV) that contained the reference and that you could use to get a pointer to another perl struct (SV) that contains the Perl scalar value. But your current code already gives you this SV* directly. With it, you can copy out an integer value or copy in a new integer value.

    The XS system generates code to copy the integer value out of the scalar and into your C variable, iReturn (which then gets passed to the C subroutine). Since you specified "OUTPUT: iReturn", code is also generated to copy the value from iReturn back into the scalar.

    Note that the scalar might not have originally contained an integer value (IV) so the first step above might prompt a conversion from the scalar's string or floating-point value into an integer (which gets cached in the SV along with any other types of values that the scalar already has).

    When the new integer value gets copied back into the scalar, then any values of other types cached in the scalar are discarded.

    - tye