http://qs321.pair.com?node_id=11120122


in reply to help with XS pointers

After you posted more code, I can see that:

const char * rtlsdr_get_device_name(index) uint32_t index

And so this:

my $device = rtlsdr_get_device_name( $index );

returns the device name as a string, given device index (integer), and not a pointer to a rtlsdr_dev_t structure as you assumed.

Given:

int rtlsdr_open(dev, index) SDR::RTLSDR **dev uint32_t index

I am guessing that one must open a device by specifying the index. The function rtlsdr_open() should probably return the status as an integer and allocates internally the device, that's what I assume when it tells you to supply the double pointer for device: "Give me a memory location and I will do the internal decoration".

Here is a stand-alone C example to demonstrate this pattern:

#include <stdio.h> #include <malloc.h> typedef struct { int a; } s_t; int open_device(s_t **dev, int index); int main(void){ s_t *device = NULL; open_device(&device, 1); printf("A=%d\n", device->a); free(device); } int open_device(s_t **dev, int index){ *dev = (s_t *)malloc(sizeof(s_t)); (*dev)->a = 42; return 1; }

How does that translate to Perl? Hmmm again a guess:

my $serial_number = "00000001"; # from dmesg output my $index = rtlsdr_get_index_by_serial( $serial_number ); # it returns + 0, this is not an error value so I think is good my $name = rtlsdr_get_device_name( $index ); print "device name '$name'\n"; my $device = undef; # = SDL::...->new() ??? # i don't think so/how? my $status = rtlsdr_open( \$device , $index) print "status $status for index $index\n";

cool project!

bw, bliako

Replies are listed 'Best First'.
Re^2: help with XS pointers
by Bpl (Scribe) on Jul 31, 2020 at 12:19 UTC
    Hi bliako, yes, you're right when assign the NULL value to the $device variable, yesterday I found a similar example from this site: http://sdr.f4gkr.org/trac/browser/gkSDR/Logiciel/rwhw/rtlsdr_iface.cpp?rev=9 which confirm also the idea of the status code (the correct return would be "0"). the initial idea was right but the return code is the same as before:
    device name 'Generic RTL2832U OEM' SDR::RTLSDR::rtlsdr_open: dev is not of type RTLSDRDevice_TPtrPtr at s +dr.pl line 13.
    Regards Edoardo M.

      Does that make sense at all?

      my $device = SDR::RTLSDR->new(); my $status = rtlsdr_open( \$device , $index); print "status $status for index $index\n";

      also see this example perlxstypemap (search for T_PTROBJ_SPECIAL) and the Netconfig example in perlxs

      Does the error message you cited corresponds for the typemap source code you have shown?

        Hi, yes the typemap is the same as before, if I try to change to "T_PTROBJ_SPECIAL" it gives this error:
        Downloads/SDR::RTLSDR/SDR (another copy)/typemap' RTLSDR.xs > RTLSDR. +xsc Can't locate object method "xstype" via package "SDR__RTLSDR *" (perha +ps you forgot to load "SDR__RTLSDR *"?) at /usr/local/share/perl/5.22 +.1/ExtUtils/ParseXS.pm line 1905, <__ANONIO__> line 38. Makefile:359: recipe for target 'RTLSDR.c' failed
        the typemap file now is:
        GNU nano 2.5.3 File: typemap + TYPEMAP SDR::RTLSDR * T_PTROBJ_SPECIAL SDR::RTLSDR ** T_PTROBJ const char * T_PV int * T_PV char * T_PV unsigned long int T_U_LONG uint8_t T_U_SHORT uint8_t * T_U_SHORT uint16_t T_U_SHORT uint32_t * T_U_SHORT uint32_t T_U_SHORT