Is it possible to store an SV in C pointer

C

cyl

Suppose I have two functions in my XS code, say funcA and funcB, after
I store an SV in a global pointer in funcA, is it possible for me to
access it in funcB? Here is my pseudo code

void *p;

void funcA()
{
p = (void*)ST(0); //suppose ST(0) is a reference
}

void funcB()
{
SV *sv = (SV*)p;
if (SvROK(sv)) ... //actually I cannot get the original SV
in funcA
}

What is the correct way? Thanks.
 
J

Joost Diepenmaat

cyl said:
Suppose I have two functions in my XS code, say funcA and funcB, after
I store an SV in a global pointer in funcA, is it possible for me to
access it in funcB?
Yes.

Here is my pseudo code

void *p;

void funcA()
{
p = (void*)ST(0); //suppose ST(0) is a reference

Better make sure it is, if that's what you're using to test it...
}

void funcB()
{
SV *sv = (SV*)p;
if (SvROK(sv)) ... //actually I cannot get the original SV
in funcA
}

Unless you're calling funcB from funcA, it's possible that the SV gets
collected after funcA() returns to perl and before funcB() gets called.

You should at least make sure you increase p's refcount when you store
it, and decrease it whenever you remove your reference to it.
 
C

cyl

Unless you're calling funcB from funcA, it's possible that the SV gets
collected after funcA() returns to perl and before funcB() gets called.
In my Perl script, that SV exists in the entire scope so it should not
be collected, shouldn't it? For example,

my $ref = [1,2,3];

funcA($ref);
funcB(); # which uses the pointer p to access $ref
__END__

This is my assumption but it seems the address I saved is not
permanent. I'm wondering what is the correct way to get the permanent
address of $ref in C. I tried SvIV, SvRV, SvPV and other APIs that I
have no clue what they are actually but all are in vain.

You should at least make sure you increase p's refcount when you store
it, and decrease it whenever you remove your reference to it.
Should I increase the refcount if I'm sure it exists on the entire
scope?
 
L

Leon Timmermans

In my Perl script, that SV exists in the entire scope so it should not
be collected, shouldn't it? For example,

my $ref = [1,2,3];

funcA($ref);
funcB(); # which uses the pointer p to access $ref
__END__

This is my assumption but it seems the address I saved is not permanent.

The address doesn't change. The address you have is $ref. Though I'm
wondering why you would store it in a void* when you can store it in a
SV*.
I'm wondering what is the correct way to get the permanent address of
$ref in C. I tried SvIV, SvRV, SvPV and other APIs that I have no clue
what they are actually but all are in vain.

In that case you should definitely reread perlapi and perlguts and make
sure you understand that all. In this case, the return value of SvRV will
be the array (though you will need to cast it to an AV* to use it).
Should I increase the refcount if I'm sure it exists on the entire
scope?

If you're absolutely sure it will exist you can leave it, but increasing/
decreasing it would be good form IMHO.

Regards.

Leon Timmermans
 
C

cyl

my $ref = [1,2,3];
funcA($ref);
funcB(); # which uses the pointer p to access $ref
__END__

The address doesn't change. The address you have is $ref. Though I'm
wondering why you would store it in a void* when you can store it in a
SV*.
But the value is changed when I access the address in funcB. In funcA,
SvROK(ST(0)) returns true while in funcB, calling SvROK with the same
address returns false. The value has been changed at that address.
That's why I suspect it is not permanent and wonder the correct
method.
 
C

cyl

But the value is changed when I access the address in funcB. In funcA,


I think my problem is that the SV I want to save is from ST(0) where
the address is on the stack and the value is getting changed
frequently. After cloning a copy of that SV by newSVsv, I have no
problem now. I'm not sure if it works to increase the reference count
of a SV on the stack.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top