Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

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

by tye (Sage)
on Jul 18, 2016 at 21:10 UTC ( [id://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 (Patriarch) 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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1168006]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 19:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found