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

Re: Need to pass an unsigned char array from an xsub back to Perl

by Eliya (Vicar)
on Mar 30, 2012 at 16:30 UTC ( #962647=note: print w/ replies, xml ) Need Help??


in reply to Need to pass an unsigned char array from an xsub back to Perl

Your code is somewhat confusing as to whether you want to return the unsigned char[16] as a Perl array/list (16 individual values), or as a scalar (Perl string of length 16).

Assuming the latter, I think you're approaching things in a much too complicated way.  Simply create a char[16] buffer in C, let XSessionID() fill it, and place a copy of it in an SV, which you then return:

#!/usr/bin/perl -wl use strict; use Inline C => <<'END_C'; SV* GenerateSessionID() { char uuid[16]; // buffer // fill buffer, i.e. mimic your XSessionID() int i; for (i=0; i<16; i++) { uuid[i] = 0xA0 + i; } return newSVpvn(uuid, 16); } END_C my $uuid = GenerateSessionID(); print join ' ', unpack("(H2)*", $uuid);

Output:

$ ./962624.pl a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af

Not using Inline::C (i.e. using a normal XSUB instead), this should translate to something like

SV * GenerateSessionID() PREINIT: char uuid[16]; CODE: XSessionID((uuid_t*)uuid); RETVAL = newSVpvn(uuid, 16); OUTPUT: RETVAL

Or, if you want to use PPCODE:

void GenerateSessionID() PREINIT: char uuid[16]; PPCODE: XSessionID((uuid_t*)uuid); ST(0) = newSVpvn(uuid, 16); sv_2mortal(ST(0)); XSRETURN(1);


Comment on Re: Need to pass an unsigned char array from an xsub back to Perl
Select or Download Code
Re^2: Need to pass an unsigned char array from an xsub back to Perl
by Anonymous Monk on Mar 30, 2012 at 17:19 UTC
    Thank you so much for the quick reply. Indeed, your solution is very elegant. I am a newbie in xsubb. I did use the second method.
    PREINIT: unsigned char uuid_arr[16]; CODE: char convert_arr[33]; int i; XGenerateSessionID((uuid_t*) &uuid_arr); memset(convert_arr,'\0',33); for(i=0; i< 16; i++){ snprintf(&convert_arr[i*2], sizeof(convert_arr)-(i*2), "%02X" +, uuid_arr[i]); } RETVAL = newSVpvn(convert_arr,33); OUTPUT: RETVAL
    If I had not converted the unsigned char back to char, the compiler complains of signedness.
Re^2: Need to pass an unsigned char array from an xsub back to Perl
by bulk88 (Priest) on Apr 01, 2012 at 16:57 UTC
    Or, if you want to use PPCODE:
    void GenerateSessionID() PREINIT: char uuid[16]; PPCODE: XSessionID((uuid_t*)uuid); ST(0) = newSVpvn(uuid, 16); sv_2mortal(ST(0)); XSRETURN(1);
    Thats quite bloated. This is less bloated.
    void GenerateSessionID() PREINIT: char uuid[16] = {0); //zero fill PPCODE: XSessionID((uuid_t*)uuid); PUSHs(sv_2mortal((newSVpvn(uuid, 16)));
    Also the OP might want to zero his UUID since we are not checking the return value of XSessionID to determine failure.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (11)
As of 2014-12-22 20:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (130 votes), past polls