xiaoyafeng has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

Is there a way to get PV address like Devel::Peek do?

use Devel::Peek; my $dd = "hello world\n"; Dump $dd; #output: SV = PV(0x55608d816050) at 0x55608d83a0a8 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x55608d8b8e90 "hello world\n"\0 CUR = 12 LEN = 14 COW_REFCNT = 1
I found the above PV address from D::P output is 0x55608d8b8e90, but how can I get this address? I tried SvPVX:
my $dd = "hello world\n"; printf("the dd string address is %x \n", cc($dd)); use Inline 'C' => <<'CODE'; unsigned int cc(SV* a){ 40 return SvPVX(a); 41 } 42 CODE # just print the dd string address is 8d8b8e90, the upper 4bytes of th +e address was truncated.
So Is there a way to get pv address as an INT value like Peek does? Do I need to create a struct to save address? TIA.

Regards,




I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

Replies are listed 'Best First'.
Re: How get PV address?
by dave_the_m (Monsignor) on Aug 05, 2019 at 09:56 UTC
    In XS code, SvPVX(sv) is correct if you're sure that sv is a valid PV value; otherwise one of the SvPV() or SvPV_force() functions/macros would be more appropriate. You're seeing a truncated version of the SvPVX() value because you're coercing it to an integer. You should be returning a suitable pointer type instead, or using an integer type like UV, which is large enough to hold a pointer.

    Dave.

      I use SvPVX is for test, since I know PV is hello world.:) The issue is I checked typemap,,in there,unsigned int int will convert to T_UV, so I don't think UV could hold this PV address. But If I change return type to char*, typemap will convert it to SV by sv_setpv.
        Well it all depends on what you want to do with the address. Are you passing it back to perl? Should perl see it as a (suitably large) integer value - i.e. the XS code returns an SVIV? What will perl do with the address?

        Dave.