Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re^2: Passing integer pointer in XS? (&)

by martin67 (Novice)
on Jul 18, 2016 at 20:32 UTC ( #1167995=note: print w/replies, xml ) Need Help??

in reply to Re: Passing integer pointer in XS? (&)
in thread Passing integer pointer in XS?

Thanks, But it still is a mystery... By using "int & " instead of "int *", the C-code looks alright and the C-function is called with the right parameters. But the value that the C-funtion writes to the int pointers are not passed back to perl.

Example in the generated C-file:

XS_EUPXS(XS_TellStick_tdSensor); /* prototype to pass -Wmissing-protot +ypes */ XS_EUPXS(XS_TellStick_tdSensor) { dVAR; dXSARGS; if (items != 6) croak_xs_usage(cv, "protocol, protocolLen, model, modelLen, id, d +ataTypes"); { char * protocol = (char *)SvPV_nolen(ST(0)) ; int protocolLen = (int)SvIV(ST(1)) ; char * model = (char *)SvPV_nolen(ST(2)) ; int modelLen = (int)SvIV(ST(3)) ; int id = (int)SvIV(ST(4)) ; int dataTypes = (int)SvIV(ST(5)) ; int RETVAL; dXSTARG; printf("id1: %d\n", id); RETVAL = tdSensor(protocol, protocolLen, model, modelLen, &id, &da +taTypes); printf("id2: %d\n", id); XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); }
I added two printf for debugging (best debug tool...) and when I run it with like this:
... my $sensorId = 1; TellStick::tdSensor($protocol, 25, $model, 25, $sensorId, $dataTypes); print "protocol: $protocol, model: $model, sensorId: $sensorId, dataT +ypes: $dataTypes\n"; I get the output id1: 1 id2: 51 protocol: mandolyn, model: temperaturehumidity, sensorId: 1, dataTypes +: 2
So it gets the correct value (51), but that is not passed back.

It looks like the XS code only sees the id parameter as an input value (casting it right), but no output is generated (except the return value). The string arguments (protocol, model), seems to work in modifying what the value is pointing to.

Should I somehow use "int *" in the XS anyway, but writing some special code for INPUT/OUTPUT in the typemap? Or is there some other way of returing the correct value?

Replies are listed 'Best First'.
Re^3: Passing integer pointer in XS? (OUTPUT:)
by tye (Sage) on Jul 18, 2016 at 20:42 UTC

    So, you'll need to add just a bit more:

    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, &da +taTypes); OUTPUT: RETVAL id dataTypes

    Sorry, it has been many years since I learned this stuff.

    - tye        

      Problem: You can't write to protocol or model safely because one of the force functions wasn't used. You might end up changing variables and constants you didn't mean to change. (They might have fixed that in 5.24?)

      use strict; use warnings; use feature qw( say ); use Inline C => <<'__EOS__'; void testing(char* s) { s[0] = 'y'; } __EOS__ my $x = "x"; my $y = $x; say "$x-$y"; testing($y); say "$x-$y";
      x-x y-y <-- Changed both $x and $y
      for (1..2) { my $y = "x"; say $y; testing($y); }
      x y <-- Changed the constant!

      Note: The caller will need to do s/\0.*// for $protocol, $model;

        I suspect that those "char *" arguments are treated such that they could be "const char *" arguments. I also suspect that "\0" characters are not expected. But if I am wrong then, yes, you need to do more work than I did. Thanks.

        - tye        

      Thank you!

      This also works! (I got another variant further down in the thread.)

      This was my first question to Perlmonks and I'm impressed by the speed and quality of the answers!

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2022-11-28 18:44 GMT
Find Nodes?
    Voting Booth?