perlguts.html

来自「perl教程」· HTML 代码 · 共 790 行 · 第 1/5 页

HTML
790
字号
</p>
<h2><a name="working_with_svs">Working with SVs</a></h2>
<p>An SV can be created and loaded with one command.  There are five types of
values that can be loaded: an integer value (IV), an unsigned integer
value (UV), a double (NV), a string (PV), and another scalar (SV).</p>
<p>The seven routines are:</p>
<pre>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSViv</span><span class="operator">(</span><span class="variable">IV</span><span class="operator">);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVuv</span><span class="operator">(</span><span class="variable">UV</span><span class="operator">);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVnv</span><span class="operator">(</span><span class="variable">double</span><span class="operator">);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVpv</span><span class="operator">(</span><span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVpvn</span><span class="operator">(</span><span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVpvf</span><span class="operator">(</span><span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="operator">...);</span>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">newSVsv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*);</span>
</pre>
<p><code>STRLEN</code> is an integer type (Size_t, usually defined as size_t in
<em>config.h</em>) guaranteed to be large enough to represent the size of
any string that perl can handle.</p>
<p>In the unlikely case of a SV requiring more complex initialisation, you
can create an empty SV with newSV(len).  If <code>len</code> is 0 an empty SV of
type NULL is returned, else an SV of type PV is returned with len + 1 (for
the NUL) bytes of storage allocated, accessible via SvPVX.  In both cases
the SV has value undef.</p>
<pre>
    <span class="variable">SV</span> <span class="variable">*sv</span> <span class="operator">=</span> <span class="variable">newSV</span><span class="operator">(</span><span class="number">0</span><span class="operator">);</span>   <span class="regex">/* no storage allocated  */</span>
    <span class="variable">SV</span> <span class="variable">*sv</span> <span class="operator">=</span> <span class="variable">newSV</span><span class="operator">(</span><span class="number">10</span><span class="operator">);</span>  <span class="regex">/* 10 (+1) bytes of uninitialised storage allocated  */</span>
</pre>
<p>To change the value of an <em>already-existing</em> SV, there are eight routines:</p>
<pre>
    <span class="variable">void</span>  <span class="variable">sv_setiv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">IV</span><span class="operator">);</span>
    <span class="variable">void</span>  <span class="variable">sv_setuv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">UV</span><span class="operator">);</span>
    <span class="variable">void</span>  <span class="variable">sv_setnv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">double</span><span class="operator">);</span>
    <span class="variable">void</span>  <span class="variable">sv_setpv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*);</span>
    <span class="variable">void</span>  <span class="variable">sv_setpvn</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">)</span>
    <span class="variable">void</span>  <span class="variable">sv_setpvf</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="operator">...);</span>
    <span class="variable">void</span>  <span class="variable">sv_vsetpvfn</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">,</span> <span class="variable">va_list</span> <span class="operator">*,</span> <span class="variable">SV</span> <span class="operator">**,</span> <span class="variable">I32</span><span class="operator">,</span> <span class="variable">bool</span> <span class="operator">*);</span>
    <span class="variable">void</span>  <span class="variable">sv_setsv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">SV</span><span class="operator">*);</span>
</pre>
<p>Notice that you can choose to specify the length of the string to be
assigned by using <code>sv_setpvn</code>, <code>newSVpvn</code>, or <code>newSVpv</code>, or you may
allow Perl to calculate the length by using <code>sv_setpv</code> or by specifying
0 as the second argument to <code>newSVpv</code>.  Be warned, though, that Perl will
determine the string's length by using <code>strlen</code>, which depends on the
string terminating with a NUL character.</p>
<p>The arguments of <code>sv_setpvf</code> are processed like <a href="../../lib/Pod/perlfunc.html#item_sprintf"><code>sprintf</code></a>, and the
formatted output becomes the value.</p>
<p><code>sv_vsetpvfn</code> is an analogue of <code>vsprintf</code>, but it allows you to specify
either a pointer to a variable argument list or the address and length of
an array of SVs.  The last argument points to a boolean; on return, if that
boolean is true, then locale-specific information has been used to format
the string, and the string's contents are therefore untrustworthy (see
<a href="../../lib/Pod/perlsec.html">the perlsec manpage</a>).  This pointer may be NULL if that information is not
important.  Note that this function requires you to specify the length of
the format.</p>
<p>The <code>sv_set*()</code> functions are not generic enough to operate on values
that have &quot;magic&quot;.  See <a href="#magic_virtual_tables">Magic Virtual Tables</a> later in this document.</p>
<p>All SVs that contain strings should be terminated with a NUL character.
If it is not NUL-terminated there is a risk of
core dumps and corruptions from code which passes the string to C
functions or system calls which expect a NUL-terminated string.
Perl's own functions typically add a trailing NUL for this reason.
Nevertheless, you should be very careful when you pass a string stored
in an SV to a C function or system call.</p>
<p>To access the actual value that an SV points to, you can use the macros:</p>
<pre>
    SvIV(SV*)
    SvUV(SV*)
    SvNV(SV*)
    SvPV(SV*, STRLEN len)
    SvPV_nolen(SV*)</pre>
<p>which will automatically coerce the actual scalar type into an IV, UV, double,
or string.</p>
<p>In the <code>SvPV</code> macro, the length of the string returned is placed into the
variable <code>len</code> (this is a macro, so you do <em>not</em> use <code>&amp;len</code>).  If you do
not care what the length of the data is, use the <code>SvPV_nolen</code> macro.
Historically the <code>SvPV</code> macro with the global variable <code>PL_na</code> has been
used in this case.  But that can be quite inefficient because <code>PL_na</code> must
be accessed in thread-local storage in threaded Perl.  In any case, remember
that Perl allows arbitrary strings of data that may both contain NULs and
might not be terminated by a NUL.</p>
<p>Also remember that C doesn't allow you to safely say <code>foo(SvPV(s, len),
len);</code>. It might work with your compiler, but it won't work for everyone.
Break this sort of statement up into separate assignments:</p>
<pre>
    <span class="variable">SV</span> <span class="variable">*s</span><span class="operator">;</span>
    <span class="variable">STRLEN</span> <span class="variable">len</span><span class="operator">;</span>
    <span class="variable">char</span> <span class="operator">*</span> <span class="variable">ptr</span><span class="operator">;</span>
    <span class="variable">ptr</span> <span class="operator">=</span> <span class="variable">SvPV</span><span class="operator">(</span><span class="regex">s, len);
    foo(ptr, len);
    </span>
</pre>
<p>If you want to know if the scalar value is TRUE, you can use:</p>
<pre>
    SvTRUE(SV*)</pre>
<p>Although Perl will automatically grow strings for you, if you need to force
Perl to allocate more memory for your SV, you can use the macro</p>
<pre>
    SvGROW(SV*, STRLEN newlen)</pre>
<p>which will determine if more memory needs to be allocated.  If so, it will
call the function <code>sv_grow</code>.  Note that <code>SvGROW</code> can only increase, not
decrease, the allocated memory of an SV and that it does not automatically
add a byte for the a trailing NUL (perl's own string functions typically do
<code>SvGROW(sv, len + 1)</code>).</p>
<p>If you have an SV and want to know what kind of data Perl thinks is stored
in it, you can use the following macros to check the type of SV you have.</p>
<pre>
    SvIOK(SV*)
    SvNOK(SV*)
    SvPOK(SV*)</pre>
<p>You can get and set the current length of the string stored in an SV with
the following macros:</p>
<pre>
    SvCUR(SV*)
    SvCUR_set(SV*, I32 val)</pre>
<p>You can also get a pointer to the end of the string stored in the SV
with the macro:</p>
<pre>
    SvEND(SV*)</pre>
<p>But note that these last three macros are valid only if <code>SvPOK()</code> is true.</p>
<p>If you want to append something to the end of string stored in an <code>SV*</code>,
you can use the following functions:</p>
<pre>
    <span class="variable">void</span>  <span class="variable">sv_catpv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*);</span>
    <span class="variable">void</span>  <span class="variable">sv_catpvn</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">);</span>
    <span class="variable">void</span>  <span class="variable">sv_catpvf</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="operator">...);</span>
    <span class="variable">void</span>  <span class="variable">sv_vcatpvfn</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">const</span> <span class="variable">char</span><span class="operator">*,</span> <span class="variable">STRLEN</span><span class="operator">,</span> <span class="variable">va_list</span> <span class="operator">*,</span> <span class="variable">SV</span> <span class="operator">**,</span> <span class="variable">I32</span><span class="operator">,</span> <span class="variable">bool</span><span class="operator">);</span>
    <span class="variable">void</span>  <span class="variable">sv_catsv</span><span class="operator">(</span><span class="variable">SV</span><span class="operator">*,</span> <span class="variable">SV</span><span class="operator">*);</span>
</pre>
<p>The first function calculates the length of the string to be appended by
using <code>strlen</code>.  In the second, you specify the length of the string
yourself.  The third function processes its arguments like <a href="../../lib/Pod/perlfunc.html#item_sprintf"><code>sprintf</code></a> and
appends the formatted output.  The fourth function works like <code>vsprintf</code>.
You can specify the address and length of an array of SVs instead of the
va_list argument. The fifth function extends the string stored in the first
SV with the string stored in the second SV.  It also forces the second SV
to be interpreted as a string.</p>
<p>The <code>sv_cat*()</code> functions are not generic enough to operate on values that
have &quot;magic&quot;.  See <a href="#magic_virtual_tables">Magic Virtual Tables</a> later in this document.</p>
<p>If you know the name of a scalar variable, you can get a pointer to its SV
by using the following:</p>
<pre>
    <span class="variable">SV</span><span class="operator">*</span>  <span class="variable">get_sv</span><span class="operator">(</span><span class="string">"package::varname"</span><span class="operator">,</span> <span class="variable">FALSE</span><span class="operator">);</span>
</pre>
<p>This returns NULL if the variable does not exist.</p>
<p>If you want to know if this variable (or any other SV) is actually <a href="../../lib/Pod/perlfunc.html#item_defined"><code>defined</code></a>,
you can call:</p>
<pre>
    SvOK(SV*)</pre>
<p>The scalar <a href="../../lib/Pod/perlfunc.html#item_undef"><code>undef</code></a> value is stored in an SV instance called <code>PL_sv_undef</code>.</p>
<p>Its address can be used whenever an <code>SV*</code> is needed. Make sure that
you don't try to compare a random sv with <code>&amp;PL_sv_undef</code>. For example
when interfacing Perl code, it'll work correctly for:</p>
<pre>
  <span class="variable">foo</span><span class="operator">(</span><span class="keyword">undef</span><span class="operator">);</span>
</pre>
<p>But won't work when called as:</p>
<pre>
  <span class="variable">$x</span> <span class="operator">=</span> <span class="keyword">undef</span><span class="operator">;</span>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?