Hi Ingo,

Glad you’re making progress!

The problem you’re having here is that you’re somewhat mixing your metaphors. 
For now, PDL mainly uses SVs for storing data. The “datasv” member of the 
struct points at the data SV, and the “data” member is set to point at its PV. 
Within e.g. the readdata function, a local C variable for the data pointer of 
ndarray “m” is created called “m_datap”, which gets updated during 
broadcasting. The “$P(m)” macro in PP expands to “m_datap”.

As you may now appreciate, assigning to that is not going to have any long-term 
effect once the function returns. You’re going to need a different approach. 
One that will operate somewhat, but isn’t the correct answer, is to assign to 
“$PDL(m)->data” instead. But you’re going to need to do memory-management 
properly, otherwise you’ll get segfaults and/or leak memory.

A more direct way to achieve the aim, staying with the SV model, is to enhance 
your MatWrapper Perl object (using XS) to be able to return its data (and 
dimensions as well), and make your get_data be pure-Perl that extracts dims, 
types and data from the MatWrapper in Perl-land, and uses PDL methods setdims, 
set_datatype, and get_dataref/upd_data to create an ndarray.

Best regards,
Ed

From: Ingo Schmid<mailto:ingo...@gmx.at>
Sent: 15 March 2022 19:52
To: perldl<mailto:pdl-general@lists.sourceforge.net>
Subject: [Pdl-general] set pointer to data (PP)


Hi,

I would like to update the pointer to piddle data. I've got a C function

void * getData(MatWrapper * mw);

that returns the pointer to opencv Mat data. I declare the piddle $m with the 
right size and data type in PMCode. Now, I can successfully say

void * data = getData($COMP(mw));

$P(m)=data;

and print the right numbers in C.

printf("m (48,48) %f\n",$m(k=>48,l=>48));  # 50.842896 - correct.

However, after returning to perl, $m(48,48) is 0 and get_dataref shows the 
wrong datdress. What's the trick to make this permanent?

Ingo

==

pp_def ('get_data',
        Pars=>'[o] m(k,l);',
        OtherPars=>'MatWrapper * mw',
        Code=>pp_line_numbers(__LINE__,
        '
                PDL_Indx ks = $SIZE(k);
                PDL_Indx ls = $SIZE(l);
                int x = cols($COMP(mw),-1);
                int y = rows($COMP(mw),-1);
                printf ("x %d : ks %d / y %d : ls %d ",x,ks,y,ls);
                if ((x == ks) && (y == ls))
                {
                        void * dat;
                      dat = getData($COMP(mw));
                        $P(m)=dat;
                } else {
                        $CROAK("Matrix size does not match!\n");
                }
                printf("m (48,48) %f\n",$m(k=>48,l=>48));
        '),
        PMCode=>pp_line_numbers(__LINE__,
        '
                sub get_data {
                        my ($mw,$p) = @_;
                        unless (ref ($p) =~ "PDL") {
                                say "rows $mw->rows";
                                $p=zeroes(float,$mw->cols,$mw->rows);
                        }
                        _get_data_int($p,$$mw);
                        say "(get_data) 48,48: ",$p->slice("48","48");
                        $p->upd_data;
                        say "(get_data) 48,48: ",$p->slice("48","48");
                        $p->transpose;
                }
                ',),
        Doc=><<"EOD",

=head2 set_data - update data of a Mat object. Size and type should match.

EOD

        );



_______________________________________________
pdl-general mailing list
pdl-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-general

Reply via email to