Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^3: Passing integer pointer in XS? (XS << Perl)

by tye (Sage)
on Jul 18, 2016 at 21:10 UTC ( #1168006=note: print w/replies, xml ) Need Help??


in reply to Re^2: Passing integer pointer in XS?
in thread Passing integer pointer in XS?

This is the kind of code that, in my experience, is one of the most likely sources of particularly troublesome errors/bugs. If you want to provide a Perlish interface, then I'd implement that in Perl code, not in XS code.

If you are having to deal with reference counts, for example, then you are highly likely to get it wrong sooner rather than later and more than once and probably not always notice the problem before you release the code.

Just write a tiny wrapper function in mundane Perl code and have that call the very, very thinly wrapped XS that calls the C code. Only do in XS those things that you really have to do in XS.

- tye        

  • Comment on Re^3: Passing integer pointer in XS? (XS << Perl)

Replies are listed 'Best First'.
Re^4: Passing integer pointer in XS? (XS << Perl)
by ikegami (Pope) on Jul 18, 2016 at 21:31 UTC
    What would be simpler than returning them in a hash? ...oh yeah, returning them in a list! Here ya go.
    void tdSensor() CODE: { char protocol[_MAX_PROTOCOL_LEN + 1]; char model[_MAX_MODEL_LEN + 1]; int id; int dataTypes; int rv = tdSensor( protocol, sizeof(protocol), model, sizeof(model), &id, &dataTypes ); if (rv != TELLSTICK_SUCCESS) { XSRETURN(0); } EXTEND(SP, 4); ST(0) = sv_2mortal(newSVpv(protocol, 0))); ST(1) = sv_2mortal(newSVpv(model, 0)); ST(2) = sv_2mortal(newIV(id)); ST(3) = sv_2mortal(newIV(dataTypes)); XSRETURN(4); }

    Usage:

    use feature qw( say ); while (my ($protocol, $model, $id, $dataTypes) = tdSensor()) { say join ', ', "protocol: $protocol", "model: $model", "sensorId: $id", "dataTypes: $dataTypes"; }

    Untested.

      If the first 4 arguments are for specifying ways to output 2 strings, then you can get simpler than that!

      int tdSensor( protocol, protocolLen, model, modelLen, id, dataTypes ) SV * protocol int protocolLen SV * model int modelLen int & id int & dataTypes CODE: { STRLEN n_a; (void) SvPV_force( protocol, n_a ); (void) SvPV_force( model, n_a ); SvGROW( protocol, protocolLen ); SvGROW( model, modelLen ); } RETVAL = tdSensor( SvPV(protocol), protocolLen, SvPV(model), modelLen, &id, &data +Types ); SvCUR_set( protocol, strlen(SvPV(protocol)) ); SvCUR_set( model, strlen(SvPV(model)) ); OUTPUT: RETVAL id dataTypes

      But much simpler (and less likely to be buggy) than even that is:

      int _tdSensor( protocol, protocolLen, model, modelLen, id, dataTypes ) char * protocol int protocolLen char * model int modelLen int & id int & dataTypes CODE: RETVAL = tdSensor( protocol, protocolLen, model, modelLen, &id, &d +ataTypes ); OUTPUT: RETVAL id dataTypes

      Plus

      sub tdSensor { my( $protocolLen, $modelLen ) = @_; $protcolLen ||= 1024; $modelLen ||= 1024; my $protocol = '\0' x $protcolLen; my $model = '\0' x $modelLen; my $id = 0; my $dataTypes = 0; my $ret = _tdSensor( $protocol, $protocolLen, $model, $modelLen, $id, $dataTypes ); s/\0.*// for $protocol, $model; return( $ret, $protocol, $model, $id, $dataTypes ); }

      Which has the significant advantage of making it much easier to improve the interface without having to futz with the super finicky XS part of the code.

      - tye        

        But much simpler (and less likely to be buggy) than even that is:

        Didn't I already demonstrate that it's quite buggy? (Ok, so you're relying on the fact that manipulating the internal buffer of the scalar works in this situation even though you're not allowed to do it. As far as I'm concerned, you can't call simple something that relies on this level of knowledge of internals.)

        If the first 4 arguments are for specifying ways to output 2 strings, then you can get simpler than that!

        Really? Cause I would need to perform some testing to verify that it's correct. All that magic is far far more complicated than just returning the values.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2020-10-29 12:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (270 votes). Check out past polls.

    Notices?