Mailing List Archive

Getting the address of a variable.
I have a slight problem, I need to get the address of a perl variable
which was used as an argument to a user defined function?

Example:

$sth->bind_param(1,$var_in_question[,%attribs])

bind_param is defined in the DB2.xs file and ends up calling a C
function which has to have the memory address of $var_in_question.

$sth->bind_param(1,$var_in_question[,%attribs])
dbd_bind_ph(arg1, arg2, arg3, arg4)
SQLBindParameter(argA,argB,argC,argD,argE,argF,argG,&arg3,argH,argI)

where &arg3 needs to be the address of $var_in_question

Thanks.
Mike

------------------------------------------------------------------------------
Michael H. Moran | Standard Disclaimer: The content of
mhm@austin.ibm.com | this posting is independent of
Commercial Performance | official IBM position.
IBM Corporation, Austin, Texas |
Re: Getting the address of a variable. [ In reply to ]
> From: mhm@austin.ibm.com
>
> I have a slight problem, I need to get the address of a perl variable
> which was used as an argument to a user defined function?
>
> Example:
>
> $sth->bind_param(1,$var_in_question[,%attribs])
>
> bind_param is defined in the DB2.xs file and ends up calling a C
> function which has to have the memory address of $var_in_question.
>
> $sth->bind_param(1,$var_in_question[,%attribs])
> dbd_bind_ph(arg1, arg2, arg3, arg4)
> SQLBindParameter(argA,argB,argC,argD,argE,argF,argG,&arg3,argH,argI)
>
> where &arg3 needs to be the address of $var_in_question
>
Mike, did you mean to post to perl5-porters instead of perldb-interest?

Anyway, the answer is... it depends on the type of the variable.
Take a look at sv.h. For example, for SVt_PV (a typical string)
sv_any in struct sv points to a struct xpv. The struct xpv xpv_pv
field is the pointer to the string.

But *don't* use it directly! sv.h defines many macros which should
be used instead of refering to the struct fields directly.

SvPVX(sv) will get you the xpv_pv value - or maybe a core dump if the
sv is not of the right type. SvPV(sv) will also get you the xpv_pv
value if the sv is a SVt_PV type (simplification) but if it's not
it'll call sv_2pv() to convert the value to a string.

For what you want to do you should *not* pass the address of the
bind_param $var_in_question to SQLBindParameter, if you do you run the
risk of memory corruption if $var_in_question is changed in any way.

I suggest that you use sv_setsv() to make a copy of $var_in_question
and then check the type (using the SvTYPE macro) and, maybe using a
switch statement, pass appropriate parameters to SQLBindParameter()
using SvIVX(), SvNVX(), SvPVX() etc after checking SvIOK(), SvNOK(),
SvPOK() etc.

Either all that or just force everything to be a string using SvPV()
and bind to that. DBD::Oracle takes this approach.

> Thanks.
> Mike
>
Tim.