import{_ as a,c as l,o as e,a4 as t}from"./chunks/framework.Cy9JvDAg.js";const k=JSON.parse('{"title":"4.6 - 函数及类型列表","description":"","frontmatter":{"title":"4.6 - 函数及类型列表","footer":true,"lastUpdated":true,"outline":"deep"},"headers":[],"relativePath":"4.6.md","filePath":"4.6.md"}'),s={name:"4.6.md"},i=t(`<h2 id="_4-6-函数及类型列表" tabindex="-1">4.6 - 函数及类型列表 <a class="header-anchor" href="#_4-6-函数及类型列表" aria-label="Permalink to &quot;4.6 - 函数及类型列表&quot;">​</a></h2><p>在这里我们列出了C API中所有的函数和类型，其按照字母顺序排列。每个函数都有一个像右侧这样的标注：<span style="color:gray;float:right;font-size:small;">[-o, +p, <em>x</em>]</span></p><p>其中第一个属性o表示这个函数会从栈上弹出多少个元素。第二个属性p表示这个函数会把多少个元素压入栈。（任何函数都会在弹出其参数后再把其结果压入栈中。）x|y的形式的属性表示会压入（弹出）x个或者y个元素；其依情况为定；一个问号?表示不知道这个函数会压入（弹出）多少个元素，这取决于它们的参数。（例如依赖了栈内的什么值。）第三个属性x会告知这个函数有没有可能抛出错误：&#39;-&#39;意味着函数不会抛出任何错误；&#39;m&#39;意味着可能会抛出内存溢出的错误；&#39;v&#39;意味着这个函数可能会抛出在下文中解释的错误；&#39;e&#39;意味着这个函数可以运行任意Lua代码，无论是直接执行还是通过调用元函数，因此可能会抛出任何错误。</p><h3 id="lua_absindex" tabindex="-1">lua_absindex <a class="header-anchor" href="#lua_absindex" aria-label="Permalink to &quot;lua_absindex {#lua_absindex}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-o, +0, <em>-</em>]</span></p><pre>int lua_absindex (lua_State *L, int idx);</pre><p>将一个可接收索引idx转换到一个等效的绝对索引（即不依赖栈大小来表示）。</p><h3 id="lua_Alloc" tabindex="-1">lua_Alloc <a class="header-anchor" href="#lua_Alloc" aria-label="Permalink to &quot;lua_Alloc {#lua_Alloc}&quot;">​</a></h3><pre>typedef void * (*lua_Alloc) (void *ud,
                             void *ptr,
                             size_t osize,
                             size_t nsize);</pre><p>由Lua状态机使用的内存分配函数类型。这个分配函数必须提供像realloc类似的功能，但不用完全一致。参数ud，为<a href="#lua_newstate">lua_newstate</a>所传递而来的一个不透明指针；参数ptr，为需要被分配/再分配/释放的内存；参数osize，为之前分配的内存块的原本大小；以及参数nsize，为新的内存块所需的大小。</p><p>当ptr不为NULL时，osize就是ptr所指向的内存块大小，即之前分配或再分配时所给的大小。</p><p>当ptr为NULL时，osize为Lua需要分配的对象种类编码。osize的可能为这些值：<a href="#lua_type">LUA_TSTRING</a>、<a href="#lua_type">LUA_TTABLE</a>、<a href="#lua_type">LUA_TFUNCTION</a>、<a href="#lua_type">LUA_TUSERDATA</a>或者<a href="#lua_type">LUA_TTHREAD</a>；这些值就是Lua正在创建的新对象的类型。当osize是其他值时，表明Lua在分配其他的东西。</p><p>Lua假定所给的分配函数有以下的行为：</p><p>当nsize为零时，分配函数必须有类似free的行为且返回NULL。</p><p>当nsize非零时，分配函数的行为必须类似realloc。尤其是当其不能满足分配请求时应当返回NULL。</p><p>这里是分配函数的一个简单实现。它被<a href="/lua5.4-manual-zh/5.1.html#luaL_newstate">luaL_newstate</a>用在辅助库中：</p><div class="language-C vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">C</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> void</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">l_alloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ud</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> *</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ptr</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">size_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> osize</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">size_t</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"> nsize</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">  (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)ud;  (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">void</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)osize;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">  /* not used */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (nsize </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">    free</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ptr);</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">    return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> NULL</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">  }</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  else</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">    return</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> realloc</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(ptr, nsize);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>注意ISO标准下的C会确保free(NULL)是没有影响的且realloc(NULL, size)等效于malloc(size)。</p><h3 id="lua_arith" tabindex="-1">lua_arith <a class="header-anchor" href="#lua_arith" aria-label="Permalink to &quot;lua_arith {#lua_arith}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-(2|1), +1, <em>e</em>]</span></p><pre>void lua_arith (lua_State *L, int op);</pre><p>对处在栈顶上的两个值（或一个，例如取负操作）做算术或位运算，其中顶部的值是第二个参数，操作会弹出这两个值然后再将结果压入到栈中。函数遵循Lua操作符的相关语法（即有可能会调用元函数）。</p><p>参数op的值必须为以下情况之一：</p><ul><li><strong>LUA_OPADD</strong>: 加法</li><li><strong>LUA_OPSUB</strong>: 减法</li><li><strong>LUA_OPMUL</strong>: 乘法</li><li><strong>LUA_OPDIV</strong>: 小数除法</li><li><strong>LUA_OPIDIV</strong>: 整除</li><li><strong>LUA_OPMOD</strong>: 取余</li><li><strong>LUA_OPPOW</strong>: 幂运算（^）</li><li><strong>LUA_OPUNM</strong>: 取负（一元操作 -）</li><li><strong>LUA_OPBNOT</strong>: 按位否（~）</li><li><strong>LUA_OPBAND</strong>: 按位与（&amp;）</li><li><strong>LUA_OPBOR</strong>: 按位或 （|）</li><li><strong>LUA_OPBXOR</strong>: 按位异或 （~）</li><li><strong>LUA_OPSHL</strong>: 左移（&lt;&lt;）</li><li><strong>LUA_OPSHR</strong>: 右移（&gt;&gt;）</li></ul><h3 id="lua_atpanic" tabindex="-1">lua_atpanic <a class="header-anchor" href="#lua_atpanic" aria-label="Permalink to &quot;lua_atpanic {#lua_atpanic}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>e</em>]</span></p><pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre><p>返回旧的并设置新的panic函数。</p><h3 id="lua_call" tabindex="-1">lua_call <a class="header-anchor" href="#lua_call" aria-label="Permalink to &quot;lua_call {#lua_call}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-(nargs+1), +nresults, <em>e</em>]</span></p><pre>void lua_call (lua_State *L, int nargs, int nresults);</pre><p>调用函数。和一般的Lua调用异常，lua_call也遵循__call元方法。所以这里“函数”一词意思是任何可被调用的值。</p><p>你必须通过这样的协议来完成调用：首先将被调用函数压入栈；接着按序压入调用参数，即第一个参数首先被压入栈。最终你调用了<a href="#lua_call">lua_call</a>；nargs为你压入栈的参数数量。当函数返回时，之前所有被压入栈的函数以及参数列表都被弹出了，所有的调用结果都被压入栈中。结果数量取决于nresults，除非nresults为LUA_MULTRET。在这种情况下，来自函数的所有结果都被压入栈；Lua会保证栈空间足以容纳返回值，但不会确保任何额外的栈空间。函数结果也是按序压入栈中的（第一个结果会首先入栈），所以在调用完成后最后一个结果会在栈顶上。</p><p>调用及运行过程中发生的任何错误都会向上传播（通过longjmp）。</p><p>下面的示例展示了在宿主程序中如何得到这段Lua代码的效果：</p><div class="language-lua vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">lua</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">a </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> f</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;how&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, t.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">x</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">14</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span></code></pre></div><p>这是C代码：</p><div class="language-C vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">C</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_getglobal</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;f&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">      /* 要调用的函数 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_pushliteral</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;how&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">  /* 第一个调用参数 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_getglobal</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;t&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">      /* 索引这个表 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_getfield</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;x&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">   /* 压入&#39;t.x&#39;的结果并作为第二个调用参数 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_remove</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">          /* 将&#39;t&#39;移出栈 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_pushinteger</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">14</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">     /*第三个调用参数 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_call</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">3</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">          /* 调用&#39;f&#39;，其中包含三个参数和一个结果值 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_setglobal</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;a&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">      /* 设为全局变量&#39;a&#39; */</span></span></code></pre></div><p>注意以上代码是<em>平衡的 balanced</em>：即在执行的最后，栈回到了一开始的状态。这被认为是一种良好的编程实现。</p><h3 id="lua_callk" tabindex="-1">lua_callk <a class="header-anchor" href="#lua_callk" aria-label="Permalink to &quot;lua_callk {#lua_callk}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-(nargs+1), +nresults, <em>e</em>]</span></p><pre>void lua_callk (lua_State *L,
                int nargs,
                int nresults,
                lua_KContext ctx,
                lua_KFunction k);</pre><p>此函数的行为完全类似于<a href="#lua_call">lua_call</a>，但是允许被调用的函数让出（参见<a href="/lua5.4-manual-zh/4.5.html">4.5</a>）。</p><h3 id="lua_CFunction" tabindex="-1">lua_CFunction <a class="header-anchor" href="#lua_CFunction" aria-label="Permalink to &quot;lua_CFunction {#lua_CFunction}&quot;">​</a></h3><pre>typedef int (*lua_CFunction) (lua_State *L);</pre><p>C函数的类型。</p><p>为了和Lua合理交流，C函数必须遵循一些约定，其必须定义传递参数和结果的方法：C函数按序从Lua的栈中接收参数（第一个参数首先入栈）。所以当函数开始时，会通过lua_gettop(L)函数来接收一定量的参数。第一个参数（如果有的话）位于索引1且最后一个参数位于lua_gettop(L)。为了给Lua返回值，C函数只需要把它们按序压入栈（第一个结果首先压入），然后在C代码中返回结果的数量。在栈中其他位于结果下边的值都会被Lua直接抛弃。和Lua函数类似，由Lua调用的C函数也可以反返回多个结果。</p><p>作为示例，以下函数接收一定量的数字参数并且返回它们的平均值与和。</p><div class="language-C vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">C</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">static</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> int</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> foo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (lua_State </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> n </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> lua_gettop</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L)</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">     /* 参数数量 */</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">  lua_Number sum </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0.0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  int</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> i;</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  for</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (i </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; i </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">&lt;=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> n; i</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">++</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">    if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_isnumber</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, i)) {</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">      lua_pushliteral</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;incorrect argument&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">      lua_error</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">    }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">    sum </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">+=</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> lua_tonumber</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, i);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">  }</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">  lua_pushnumber</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, sum</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">n);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> /* 第一个结果 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">  lua_pushnumber</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, sum);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">   /* 第二个结果 */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">  return</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">                 /* 结果个数*/</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="lua_checkstack" tabindex="-1">lua_checkstack <a class="header-anchor" href="#lua_checkstack" aria-label="Permalink to &quot;lua_checkstack {#lua_checkstack}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_checkstack (lua_State *L, int n);</pre><p>确保栈中最少有n个额外的空间，即你可以安全地压入n个值。如果不能满足要求它会返回false，要么是因为其所要求的大小大于一个固定的最大值（通常至少允许有几千个元素），要么是因为它不能为额外的空间分配内存了。这个函数永远不会收缩栈；如果栈已经有足够的空间容纳额外元素了，那么它会保持不变。</p><h3 id="lua_close" tabindex="-1">lua_close <a class="header-anchor" href="#lua_close" aria-label="Permalink to &quot;lua_close {#lua_close}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void lua_close (lua_State *L);</pre><p>在Lua主线程中关闭所有待关闭变量，在给定的Lua状态机上释放所有变量（如果有的话，调用相关的GC元函数），然后释放由这个状态所使用的所有动态内存。</p><p>在一些平台上，你也许不需要调用此函数，因为在宿主程序结束的时候会自然释放所有的资源。另一方面，而创建了多个状态机的长时间运行的程序，例如守护精华曾或者Web服务，可能要在不需要的时候晶块关闭状态机。</p><h3 id="lua_closeslot" tabindex="-1">lua_closeslot <a class="header-anchor" href="#lua_closeslot" aria-label="Permalink to &quot;lua_closeslot {#lua_closeslot}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>e</em>]</span></p><pre>void lua_closeslot (lua_State *L, int index);</pre><p>关闭所给索引处的待关闭插槽并设置其值为<strong>nil</strong>。索引必须是之前被标记为要关闭（参见<a href="#lua_toclose">lua_toclose</a>）的最后一个，但其仍然存活（即尚未关闭）。</p><p>通过此函数调用时的__close元函数不可以让出。</p><p>（此函数于版本5.4.3引入。）</p><h3 id="lua_closethread" tabindex="-1">lua_closethread <a class="header-anchor" href="#lua_closethread" aria-label="Permalink to &quot;lua_closethread {#lua_closethread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +?, <em>-</em>]</span></p><pre>int lua_closethread (lua_State *L, lua_State *from);</pre><p>重置一个Lua线程，清理器调用栈并关闭所有的待关闭变量。最后返回一个状态码：<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>表示在这个Lua线程中没有错误（要么是因为线程已经停止了或者在关闭函数中本身发生的错误），或者一个其他的错误状态码。在发生错误的情况下，会将错误对象保留在栈顶。</p><p>参数from表示正在重置L的协程。如果没有这个协程，此参数可以为NULL。</p><p>（此函数于版本5.4.6引入。）</p><h3 id="lua_compare" tabindex="-1">lua_compare <a class="header-anchor" href="#lua_compare" aria-label="Permalink to &quot;lua_compare {#lua_compare}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>e</em>]</span></p><pre>int lua_compare (lua_State *L, int index1, int index2, int op);</pre><p>比较两个Lua值。处于index1的值和index2的值比较后能满足op的话就会返回1，否则返回0；并且遵循Lua操作符的相关语法约定（即可能会调用元表）。任何无效索引也会导致返回0。</p><p>op值必须为以下常量：</p><ul><li><strong>LUA_OPEQ</strong>：比较是否相等（==）</li><li><strong>LUA_OPLT</strong>：比较是否小于（&lt;）</li><li><strong>LUA_OPLE</strong>：比较是否小于等于（&lt;=）</li></ul><h3 id="lua_concat" tabindex="-1">lua_concat <a class="header-anchor" href="#lua_concat" aria-label="Permalink to &quot;lua_concat {#lua_concat}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-n, +1, <em>e</em>]</span></p><pre>void lua_concat (lua_State *L, int n);</pre><p>连接在栈顶上的n个值，弹出这些值并将结果放到栈顶上。如果n为1，则结果就是在栈中的单一值（即此函数什么都不会干）；如果n为0，则结果为空字符串。连接操作遵循之前提到的一般Lua语法（参见<a href="/lua5.4-manual-zh/3.4.6.html">3.4.6</a>）。</p><h3 id="lua_copy" tabindex="-1">lua_copy <a class="header-anchor" href="#lua_copy" aria-label="Permalink to &quot;lua_copy {#lua_copy}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void lua_copy (lua_State *L, int fromidx, int toidx);</pre><p>拷贝fromidx索引处的值到有效索引toidx处的值，并替换掉这个位置上的值。其他位置上的值不受影响。</p><h3 id="lua_createtable" tabindex="-1">lua_createtable <a class="header-anchor" href="#lua_createtable" aria-label="Permalink to &quot;lua_createtable {#lua_createtable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>void lua_createtable (lua_State *L, int narr, int nrec);</pre><p>创建一个空表并压入栈中。参数narr指出表将会是个序列且有多少个元素；参数nrec指出此表将会有多少个元素。Lua可能会使用这些指示值来提前分配内存给新表。当你提前知道表中会有多少个元素时，提前分配内存有助于性能提升。否则你可以使用<a href="#lua_newtable">lua_newtable</a>函数。</p><h3 id="lua_dump" tabindex="-1">lua_dump <a class="header-anchor" href="#lua_dump" aria-label="Permalink to &quot;lua_dump {#lua_dump}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_dump (lua_State *L,
                        lua_Writer writer,
                        void *data,
                        int strip);</pre><p>将Lua函数转存为一个二进制块。从栈顶上接收一个函数并产生其二进制块，如果之后加载这个块，那么会产生一个转存的函数相等效的函数。每产出一部分二进制块，<a href="#lua_dump">lua_dump</a>都会调用writer（参见<a href="#lua_Writer">lua_Writer</a>）并使用所给的data参数指向的缓冲块来写入。</p><p>如果strip为true，则表示二进制块可能不会包含所有与函数相关的调试信息，以节省存储空间。</p><p>返回值时最后一次调用writer所返回的错误码；0表示无错误。</p><p>此接口不会弹出在栈上的Lua函数。</p><h3 id="lua_error" tabindex="-1">lua_error <a class="header-anchor" href="#lua_error" aria-label="Permalink to &quot;lua_error {#lua_error}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>v</em>]</span></p><pre>int lua_error (lua_State *L);</pre><p>抛出一个Lua错误，使用栈顶上的值作为错误对象。此函数会发生long jump，因此永不返回（参见<a href="/lua5.4-manual-zh/5.1.html#luaL_error">luaL_error</a>）。</p><h3 id="lua_gc" tabindex="-1">lua_gc <a class="header-anchor" href="#lua_gc" aria-label="Permalink to &quot;lua_gc {#lua_gc}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_gc (lua_State *L, int what, ...);</pre><p>GC行为控制。</p><p>此函数会执行一些任务，任务通过参数what的值来指定。下面列出了各选项以及对应所需的额外函数。</p><ul><li><strong>LUA_GCCOLLECT</strong>：执行一次完整的GC循环。</li><li><strong>LUA_GCSTOP</strong>：停止GC。</li><li><strong>LUA_GCRESTART</strong>：重启GC。</li><li><strong>LUA_GCCOUNT</strong>：返回Lua当前使用的内存量（单位Kbytes）。</li><li><strong>LUA_GCSTEP(int stepsize):</strong>：执行步进GC的一小步，步长为stepsize（Kbytes）。</li><li><strong>LUA_GCISRUNNING</strong>：返回一个布尔值以表明收集器是否在运行中。</li><li><strong>LUA_GCINC (int pause, int stepmul, stepsize)</strong>：根据所给参数将GC变为步进模式（参见<a href="/lua5.4-manual-zh/2.5.1.html">2.5.1</a>）。并返回之前使用的模式（LUA_GCGEN 或是 LUA_GCINC）。</li><li><strong>LUA_GCGEN (int minormul, int majormul)</strong>：根据所给参数将GC变为代际模式（参见<a href="/lua5.4-manual-zh/2.5.1.html">2.5.1</a>）。并返回之前使用的模式（LUA_GCGEN 或是 LUA_GCINC）。</li></ul><p>更多细节请参见<a href="/lua5.4-manual-zh/6.1.html#collectgarbage">collectgarbage</a>。</p><p>此函数不应当在终结器中调用。</p><h3 id="lua_getallocf" tabindex="-1">lua_getallocf <a class="header-anchor" href="#lua_getallocf" aria-label="Permalink to &quot;lua_getallocf {#lua_getallocf}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Alloc lua_getallocf (lua_State *L, void **ud);</pre><p>返回所给状态机使用的内存分配函数。当ud不为NULL时，Lua会将对应状态机所使用的内存分配函数存到*ud中。</p><h3 id="lua_getfield" tabindex="-1">lua_getfield <a class="header-anchor" href="#lua_getfield" aria-label="Permalink to &quot;lua_getfield {#lua_getfield}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>e</em>]</span></p><pre>int lua_getfield (lua_State *L, int index, const char *k);</pre><p>将t[k]的值压入栈中，此处t为给出的索引所处的值。和在Lua代码中一样，此函数可能会触发&quot;index&quot;事件的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。</p><p>返回值为压入栈中的值的类型。</p><h3 id="lua_getextraspace" tabindex="-1">lua_getextraspace <a class="header-anchor" href="#lua_getextraspace" aria-label="Permalink to &quot;lua_getextraspace {#lua_getextraspace}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void *lua_getextraspace (lua_State *L);</pre><p>返回指向所给Lua状态机中一块原始内存区域的指针。程序将这块区域用于任何目的，Lua不会将其用在任何事上。</p><p>每个Lua线程都有这块区域，其由Lua主线程的区域拷贝而来。</p><p>默认情况下，这块内存的大小为void指针的大小，不过你可以使用不同的大小来重新编译Lua(参见 luaconf.h 中的 LUA_EXTRASPACE)。</p><h3 id="lua_getglobal" tabindex="-1">lua_getglobal <a class="header-anchor" href="#lua_getglobal" aria-label="Permalink to &quot;lua_getglobal {#lua_getglobal}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>e</em>]</span></p><pre>int lua_getglobal (lua_State *L, const char *name);</pre><p>将名为name的全局变量的值压入栈中。返回值为这个全局变量的类型。</p><h3 id="lua_geti" tabindex="-1">lua_geti <a class="header-anchor" href="#lua_geti" aria-label="Permalink to &quot;lua_geti {#lua_geti}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>e</em>]</span></p><pre>int lua_geti (lua_State *L, int index, lua_Integer i);</pre><p>将t[i]的值压入栈中，这里的t为给出索引的值。和在Lua代码中一样，此函数可能会触发&quot;index&quot;事件的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。</p><h3 id="lua_getmetatable" tabindex="-1">lua_getmetatable <a class="header-anchor" href="#lua_getmetatable" aria-label="Permalink to &quot;lua_getmetatable {#lua_getmetatable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +(0|1), <em>-</em>]</span></p><pre>int lua_getmetatable (lua_State *L, int index);</pre><p>如果给出索引的值中含有元表，那么此函数会将其元表压入栈中然后返回1。否则，此函数返回且不会向栈中压入任何值。</p><h3 id="lua_gettable" tabindex="-1">lua_gettable <a class="header-anchor" href="#lua_gettable" aria-label="Permalink to &quot;lua_gettable {#lua_gettable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +1, <em>e</em>]</span></p><pre>int lua_gettable (lua_State *L, int index);</pre><p>将t[k]的值压入栈中，这里的t为给出索引的值，k为栈顶上的值。</p><p>此函数从栈中弹出键，再将结果压入同样的位置。和在Lua中一样，此函数可能会触发&quot;index&quot;事件的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。</p><h3 id="lua_gettop" tabindex="-1">lua_gettop <a class="header-anchor" href="#lua_gettop" aria-label="Permalink to &quot;lua_gettop {#lua_gettop}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_gettop (lua_State *L);</pre><p>返回栈顶元素的索引。因为索引是从1开始的，所以这里的结果就是栈中元素的数量；特殊情况下是0，表明栈是空的。</p><h3 id="lua_getiuservalue" tabindex="-1">lua_getiuservalue <a class="header-anchor" href="#lua_getiuservalue" aria-label="Permalink to &quot;lua_getiuservalue {#lua_getiuservalue}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>int lua_getiuservalue (lua_State *L, int index, int n);</pre><p>将给出索引处的 full userdata 关联的第n个user值压入栈中，并且返回此值的类型。</p><p>如果这个 userdata 没有这个值，则压入<strong>nil</strong>并且返回<a href="/lua5.4-manual-zh/4.1.2.html">LUA_TNONE</a>。</p><h3 id="lua_insert" tabindex="-1">lua_insert <a class="header-anchor" href="#lua_insert" aria-label="Permalink to &quot;lua_insert {#lua_insert}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +1, <em>-</em>]</span></p><pre>void lua_insert (lua_State *L, int index);</pre><p>将栈顶元素移动到有效的index处，上移其上边的元素到空出来的位置。此函数不可以使用虚拟索引，因为虚拟索引并不真实存在于栈上。</p><h3 id="lua_Integer" tabindex="-1">lua_Integer <a class="header-anchor" href="#lua_Integer" aria-label="Permalink to &quot;lua_Integer {#lua_Integer}&quot;">​</a></h3><pre>typedef ... lua_Integer;</pre><p>Lua中的整数类型。</p><p>此类型默认为 long long，（通常是一个64位整数），但是其可以改为 long 或者 int (通常是一个32位整数)。（参见 luaconf.h 中的 LUA_INT_TYPE 。）</p><p>Lua还定义了常量 LUA_MININTEGER 和 LUA_MAXINTEGER，用于表示此类型的最大值和最小值。</p><h3 id="lua_isboolean" tabindex="-1">lua_isboolean <a class="header-anchor" href="#lua_isboolean" aria-label="Permalink to &quot;lua_isboolean {#lua_isboolean}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isboolean (lua_State *L, int index);</pre><p>当给出索引的值为布尔类型时则返回1，否则返回0。</p><h3 id="lua_iscfunction" tabindex="-1">lua_iscfunction <a class="header-anchor" href="#lua_iscfunction" aria-label="Permalink to &quot;lua_iscfunction {#lua_iscfunction}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_iscfunction (lua_State *L, int index);</pre><p>当给出索引的值为C函数类型时则返回1，否则返回0。</p><h3 id="lua_isinteger" tabindex="-1">lua_isinteger <a class="header-anchor" href="#lua_isinteger" aria-label="Permalink to &quot;lua_isinteger {#lua_isinteger}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isinteger (lua_State *L, int index);</pre><p>当给出索引的值为整数类型时则返回1，否则返回0。</p><h3 id="lua_islightuserdata" tabindex="-1">lua_islightuserdata <a class="header-anchor" href="#lua_islightuserdata" aria-label="Permalink to &quot;lua_islightuserdata {#lua_islightuserdata}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_islightuserdata (lua_State *L, int index);</pre><p>当给出索引的值为 light userdata 时则返回1，否则返回0。</p><h3 id="lua_isnil" tabindex="-1">lua_isnil <a class="header-anchor" href="#lua_isnil" aria-label="Permalink to &quot;lua_isnil {#lua_isnil}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isnil (lua_State *L, int index);</pre><p>当给出索引的值为<strong>nil</strong>时则返回1，否则返回0。</p><h3 id="lua_isnone" tabindex="-1">lua_isnone <a class="header-anchor" href="#lua_isnone" aria-label="Permalink to &quot;lua_isnone {#lua_isnone}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isnone (lua_State *L, int index);</pre><p>当给出索引的值无效时则返回1，否则返回0。</p><h3 id="lua_isnoneornil" tabindex="-1">lua_isnoneornil <a class="header-anchor" href="#lua_isnoneornil" aria-label="Permalink to &quot;lua_isnoneornil {#lua_isnoneornil}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isnoneornil (lua_State *L, int index);</pre><p>当给出索引的值无效或为<strong>nil</strong>时则返回1，否则返回0。</p><h3 id="lua_isnumber" tabindex="-1">lua_isnumber <a class="header-anchor" href="#lua_isnumber" aria-label="Permalink to &quot;lua_isnumber {#lua_isnumber}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isnumber (lua_State *L, int index);</pre><p>当给出索引的值为数字类型或是可转换为数字的字符串类型时则返回1，否则返回0。</p><h3 id="lua_isstring" tabindex="-1">lua_isstring <a class="header-anchor" href="#lua_isstring" aria-label="Permalink to &quot;lua_isstring {#lua_isstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isstring (lua_State *L, int index);</pre><p>当给出索引的值为字符串类型或数字类型（数字必然可以转换为字符串）时则返回1，否则返回0。</p><h3 id="lua_istable" tabindex="-1">lua_istable <a class="header-anchor" href="#lua_istable" aria-label="Permalink to &quot;lua_istable {#lua_istable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_istable (lua_State *L, int index);</pre><p>当给出索引的值为表类型时则返回1，否则返回0。</p><h3 id="lua_isthread" tabindex="-1">lua_isthread <a class="header-anchor" href="#lua_isthread" aria-label="Permalink to &quot;lua_isthread {#lua_isthread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isthread (lua_State *L, int index);</pre><p>当给出索引的值为Lua线程（协程）类型时则返回1，否则返回0。</p><h3 id="lua_isuserdata" tabindex="-1">lua_isuserdata <a class="header-anchor" href="#lua_isuserdata" aria-label="Permalink to &quot;lua_isuserdata {#lua_isuserdata}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isuserdata (lua_State *L, int index);</pre><p>当给出索引的值为 (full/light) user data 类型时则返回1，否则返回0。</p><h3 id="lua_isyieldable" tabindex="-1">lua_isyieldable <a class="header-anchor" href="#lua_isyieldable" aria-label="Permalink to &quot;lua_isyieldable {#lua_isyieldable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_isyieldable (lua_State *L);</pre><p>当所给的协程（即传入的lua_State类型）可以让出时则返回1，否则返回0。</p><h3 id="lua_KContext" tabindex="-1">lua_KContext <a class="header-anchor" href="#lua_KContext" aria-label="Permalink to &quot;lua_KContext {#lua_KContext}&quot;">​</a></h3><pre>typedef ... lua_KContext;</pre><p>延续函数的上下文类型。其必须是一个数字类型。当 intptr_t 可用时，此类型被定义为 intptr_t 类型，所以它也可以存指针。否则，其被定义为 ptrdiff_t 类型。</p><h3 id="lua_KFunction" tabindex="-1">lua_KFunction <a class="header-anchor" href="#lua_KFunction" aria-label="Permalink to &quot;lua_KFunction {#lua_KFunction}&quot;">​</a></h3><pre>typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);</pre><p>延续函数的类型（参见<a href="/lua5.4-manual-zh/4.5.html">4.5</a>）。</p><h3 id="lua_len" tabindex="-1">lua_len <a class="header-anchor" href="#lua_len" aria-label="Permalink to &quot;lua_len {#lua_len}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>e</em>]</span></p><pre>void lua_len (lua_State *L, int index);</pre><p>返回给出索引的值的长度。其等效于Lua代码中的&quot;#&quot;操作（参见<a href="/lua5.4-manual-zh/3.4.7.html">3.4.7</a>），可能会触发&quot;length&quot;事件的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。结果会被压入到栈中。</p><h3 id="lua_load" tabindex="-1">lua_load <a class="header-anchor" href="#lua_load" aria-label="Permalink to &quot;lua_load {#lua_load}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>int lua_load (lua_State *L,
              lua_Reader reader,
              void *data,
              const char *chunkname,
              const char *mode);</pre><p>加载Lua代码块但不运行。如果没有错误发生，<a href="#lua_load">lua_load</a>会将编译后的块作为一个Lua函数压入栈中。否则，它将压入错误对象。</p><p><a href="#lua_load">lua_load</a>函数通过用户提供的reader函数来读取代码块（参见<a href="#lua_reader">lua_Reader</a>）。data参数是一个要传递给reader的不透明值。</p><p>参数chunkname是所给代码块的名称，会被用在错误消息和调试信息中（参见<a href="/lua5.4-manual-zh/4.7.html">4.7</a>）。</p><p><a href="#lua_load">lua_load</a>会自动检测传入的代码块是文本还是二进制格式然后用合适的方式加载它（参见 luac 程序）。字符串参数mode的工作方式和<a href="/lua5.4-manual-zh/6.1.html#load">load</a>函数中的相同，另有不同的是，当mode值为NULL时等效于字符串&quot;bt&quot;。</p><p><a href="#lua_load">lua_load</a>内部也使用了栈，所以reader函数在返回是必须使得栈保持不变。</p><p><a href="#lua_load">lua_load</a>可能返回 LUA_OK、 LUA_ERRSYNTAX 或是 LUA_ERRMEM （此函数也可能返回与read函数所产生错误相关的值，参见<a href="/lua5.4-manual-zh/4.4.1.html">4.4.1</a>）。</p><p>如果加载得到的函数有上值，那么第一个上值就会设在全局环境中的值中，全局环境被存在注册表中的 LUA_RIDX_GLOBALS 索引处（参见<a href="/lua5.4-manual-zh/4.3.html">4.3</a>）。加载主代码块时，这个上值会是变量 _ENV（参见<a href="/lua5.4-manual-zh/2.2.html">2.2</a>）。其他上值会被初始化为<strong>nil</strong>。</p><h3 id="lua_newstate" tabindex="-1">lua_newstate <a class="header-anchor" href="#lua_newstate" aria-label="Permalink to &quot;lua_newstate {#lua_newstate}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_State *lua_newstate (lua_Alloc f, void *ud);</pre><p>创建一个独立的Lua状态机并返回其Lua主协程。如果不能创建状态机（可能是因为内存不足）时返回 NULL 。参数 f 为内存分配函数；Lua在这个状态机中的所有内存分配都将使用这个函数（参见<a href="#lua_Alloc">lua_Alloc</a>）。第二个参数 ud 是一个不透明指针，Lua每次调用内存分配时都会将其传入。</p><h3 id="lua_newtable" tabindex="-1">lua_newtable <a class="header-anchor" href="#lua_newtable" aria-label="Permalink to &quot;lua_newtable {#lua_newtable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>void lua_newtable (lua_State *L);</pre><p>创建一个表并将其压入栈中。等效于 lua_createtable(L, 0, 0) 。</p><h3 id="lua_newthread" tabindex="-1">lua_newthread <a class="header-anchor" href="#lua_newthread" aria-label="Permalink to &quot;lua_newthread {#lua_newthread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>lua_State *lua_newthread (lua_State *L);</pre><p>创建一个Lua线程，并将其压入栈中，然后返回一个代表这个新Lua线程的<a href="#lua_State">lua_State</a>指针。所返回的新Lua线程与传递进来的原线程共享同一个全局环境，但是有独立执行栈。</p><p>Lua线程和其他Lua对象一样，也受GC的管理。</p><h3 id="lua_newuserdatauv" tabindex="-1">lua_newuserdatauv <a class="header-anchor" href="#lua_newuserdatauv" aria-label="Permalink to &quot;lua_newuserdatauv {#lua_newuserdatauv}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue);</pre><p>此函数会创建一个新的 full userdata 并将其压入栈中。其引用了 nuvalue 个Lua值，称为 user value，加上引用了一块 size 字节的原始内存。（这些 user value 可以通过<a href="#lua_setiuservalue">lua_setiuservalue</a>和<a href="#lua_getiuservalue">lua_getiuservalue</a>函数来设置或读取。）</p><p>此函数返回关联内存块的地址。Lua会确保在 userdata 活跃期间其关联的内存块不会失效（参见<a href="/lua5.4-manual-zh/2.5.html">2.5</a>）。此外，如果 userdata 被标记为可终结的（参见<a href="/lua5.4-manual-zh/2.5.3.html">2.5.3</a>），那么这个地址会被保留到调用终结器为止。</p><h3 id="lua_next" tabindex="-1">lua_next <a class="header-anchor" href="#lua_next" aria-label="Permalink to &quot;lua_next {#lua_next}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +(2|0), <em>v</em>]</span></p><pre>int lua_next (lua_State *L, int index);</pre><p>从栈中弹出一个键，然后从给出索引处的table中取出一对键值压入栈中，这个键值对就在之前弹出的键后边的位置。如果表中没有更多的元素，那么<a href="#lua_next">lua_next</a>返回0并且不会压栈。</p><p>通常表的遍历会像这样：</p><div class="language-C vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">C</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">/* 表在栈中&#39;t&#39;索引的位置 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_pushnil</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L);</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">  /* 第一个键 */</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">while</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_next</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, t) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">!=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 0</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">  /* 键在-2索引上，键值在-1索引上 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">  printf</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%s</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> - </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">%s\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">         lua_typename</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)),</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">         lua_typename</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_type</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">-</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)));</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">  /* 移走键值引用；留着键给下一轮迭代使用 */</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">  lua_pop</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><p>当遍历表时应当避免直接对键调用<a href="#lua_tolstring">lua_tolstring</a>，除非你知道键确实是个字符串。<a href="#lua_tolstring">lua_tolstring</a>可能会改变给出索引处的值；这样会和下一次调用<a href="#lua_next">lua_next</a>混淆在一起。</p><p>当给的键既不是<strong>nil</strong>也不存在于表中时，此函数可能会抛出错误。与在遍历过程中更改表相关的注意事项请参见<a href="/lua5.4-manual-zh/6.1.html#next">next</a>函数。</p><h3 id="lua_Number" tabindex="-1">lua_Number <a class="header-anchor" href="#lua_Number" aria-label="Permalink to &quot;lua_Number {#lua_Number}&quot;">​</a></h3><pre>typedef ... lua_Number;</pre><p>Lua中的浮点数类型。</p><p>默认为 double 类型，但是你可以改为 float 或 long double 。（参见 luaconf.h 中的 LUA_FLOAT_TYPE 。）</p><h3 id="lua_numbertointeger" tabindex="-1">lua_numbertointeger <a class="header-anchor" href="#lua_numbertointeger" aria-label="Permalink to &quot;lua_numbertointeger {#lua_numbertointeger}&quot;">​</a></h3><pre>int lua_numbertointeger (lua_Number n, lua_Integer *p);</pre><p>常见将Lua浮点数转换为Lua整数；浮点数 n 一定有整数值。如果这个整数值在Lua整数的取值范围内，那么会将此浮点数转换为一个整数并赋值给 *p 。这个宏的结果是个布尔值，以表示转换是否成功。（要知道，由于四舍五入，没有这个宏很难正确执行范围测试。）</p><p>此宏可能会多次计算其参数。</p><h3 id="lua_pcall" tabindex="-1">lua_pcall <a class="header-anchor" href="#lua_pcall" aria-label="Permalink to &quot;lua_pcall {#lua_pcall}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-(nargs+1), +(nresults|1), <em>-</em>]</span></p><pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre><p>在保护模式下调用函数（或者可调用的对象）。</p><p>nargs 和 nresults 参数的含义与<a href="#lua_call">lua_call</a>中一样。如果在调用期间没有发生错误，那么<a href="#lua_pcall">lua_pcall</a>的行为会和<a href="#lua_call">lua_call</a>类似。然而，如果发生了任何错误，<a href="#lua_pcall">lua_pcall</a>会捕获它，并将一个值（即错误对象）压入到栈中，然后返回一个错误码。和<a href="#lua_call">lua_call</a>类似，<a href="#lua_pcall">lua_pcall</a>通常会把这个函数和它的参数从栈上移除。</p><p>如果 msgh 为0，那么返回的错误对象会被原样放在栈中。否则，msgh 为<em>错误处消息理函数</em>在栈中的索引位置（此索引不可以是虚拟索引）。在运行时发生错误的情况下，将会带上错误对象一起调用处理函数，调用结果会通过<a href="#lua_pcall">lua_pcall</a>返回到栈上。</p><p>通常此处理函数被用来给错误对象添加更多的错误信息，例如栈的回溯。这些信息不能在<a href="#lua_pcall">lua_pcall</a>返回后再收集，因为那个时候栈已经展开。</p><p><a href="#lua_pcall">lua_pcall</a>函数会返回这些状态码中的一个：<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>、<a href="/lua5.4-manual-zh/4.4.1.html">LUA_ERRRUN</a>、<a href="/lua5.4-manual-zh/4.4.1.html">LUA_ERRMEM</a>或者<a href="/lua5.4-manual-zh/4.4.1.html">LUA_ERRERR</a>。</p><h3 id="lua_pcallk" tabindex="-1">lua_pcallk <a class="header-anchor" href="#lua_pcallk" aria-label="Permalink to &quot;lua_pcallk {#lua_pcallk}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-(nargs+1), +(nresults|1), <em>-</em>]</span></p><pre>int lua_pcallk (lua_State *L,
                int nargs,
                int nresults,
                int msgh,
                lua_KContext ctx,
                lua_KFunction k);</pre><p>此函数的行为类似于<a href="#lua_pcall">lua_pcall</a>，不同在于它允许调用的函数让出（参见<a href="/lua5.4-manual-zh/4.5.html">4.5</a>）。</p><h3 id="lua_pop" tabindex="-1">lua_pop <a class="header-anchor" href="#lua_pop" aria-label="Permalink to &quot;lua_pop {#lua_pop}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-n, +0, <em>e</em>]</span></p><pre>void lua_pop (lua_State *L, int n);</pre><p>从栈上弹出 n 个元素。其实现为一个用宏包装起来的 <a href="#lua_settop">lua_settop</a> 调用。</p><h3 id="lua_pushboolean" tabindex="-1">lua_pushboolean <a class="header-anchor" href="#lua_pushboolean" aria-label="Permalink to &quot;lua_pushboolean {#lua_pushboolean}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushboolean (lua_State *L, int b);</pre><p>将一个布尔值 b 压入栈中。</p><h3 id="lua_pushcclosure" tabindex="-1">lua_pushcclosure <a class="header-anchor" href="#lua_pushcclosure" aria-label="Permalink to &quot;lua_pushcclosure {#lua_pushcclosure}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-n, +1, <em>m</em>]</span></p><pre>void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);</pre><p>将一个C闭包压入栈中。此函数接收一个指向C函数的指针并将其作为 function 类型的Lua值压入栈中，当这个值被调用的时候会触发相关的C函数。参数 n 表示这个函数将会有多少个上值（参见<a href="/lua5.4-manual-zh/4.2.html">4.2</a>）。</p><p>任何可以被Lua调用的函数都必须正确遵循传参和返回的协议（参见<a href="#lua_CFunction">lua_CFunction</a>）。</p><p>当一个C函数被创建，它可能会关联一些值，所以被称为上值 upvalues ；这些上值可以在调用期间被函数访问。这种关联关系被称为C闭包（参见<a href="/lua5.4-manual-zh/4.2.html">4.2</a>）。要创建一个C闭包，首先就必须将上值的初始值压入栈中。（当存在多个上值得时候，第一个上值首先压入，以此类推。）然后调用<a href="#lua_pushcclosure">lua_pushcclosure</a>来创建C函数并压入栈中，其中参数 n 指出了函数有多少个关联的值。<a href="#lua_pushcclosure">lua_pushcclosure</a>会将这些值从栈上弹出。</p><p>n 的最大值为255。</p><p>当 n 为零时，此函数创建的是一个<em>轻量级C函数 light C function</em> ，其只是一个C函数指针。这种情况下永远不会抛出内存错误。</p><h3 id="lua_pushcfunction" tabindex="-1">lua_pushcfunction <a class="header-anchor" href="#lua_pushcfunction" aria-label="Permalink to &quot;lua_pushcfunction {#lua_pushcfunction}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre><p>将一个C函数压入栈中。此函数等效于不带上值的<a href="#lua_pushcclosure">lua_pushcclosure</a>调用。</p><h3 id="lua_pushfstring" tabindex="-1">lua_pushfstring <a class="header-anchor" href="#lua_pushfstring" aria-label="Permalink to &quot;lua_pushfstring {#lua_pushfstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>v</em>]</span></p><pre>const char *lua_pushfstring (lua_State *L, const char *fmt, ...);</pre><p>将一个格式化字符串压入到栈中并返回这个字符串的指针（参见<a href="/lua5.4-manual-zh/4.1.3.html">4.1.3</a>）。其和ISO标准下的C函数 sprintf 类似，但是有两点不同之处。第一点，你无需为结果分配空间；这个结果是一个Lua字符串所以会由Lua来管理它的内存分配（以及通过GC释放内存）。第二点，其转义符有很多限制。不支持标志、宽度或是精度。转义符只支持&#39;%%&#39;（插入一个百分号字符）、&#39;%s&#39;（插入一个C风格字符串，即以0为结尾，不限制大小）、&#39;%f&#39;（插入一个<a href="#lua_Number">lua_Number</a>）、&#39;%I&#39;（插入一个<a href="#lua_Integer">lua_Integer</a>）、&#39;%p&#39;（插入一个指针值）、&#39;%d&#39;（插入一个 int ）、&#39;%c&#39;（插入一个由 int 值表示编码值的字符）、以及&#39;%U&#39;（插入一个 long int 作为一个UTF-8的字节序）。</p><p>此函数会在内存溢出或者发生了无效转义的时候抛出错误。</p><h3 id="lua_pushglobaltable" tabindex="-1">lua_pushglobaltable <a class="header-anchor" href="#lua_pushglobaltable" aria-label="Permalink to &quot;lua_pushglobaltable {#lua_pushglobaltable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushglobaltable (lua_State *L);</pre><p>将全局环境压入栈中。</p><h3 id="lua_pushinteger" tabindex="-1">lua_pushinteger <a class="header-anchor" href="#lua_pushinteger" aria-label="Permalink to &quot;lua_pushinteger {#lua_pushinteger}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushinteger (lua_State *L, lua_Integer n);</pre><p>压入一个值为 n 的整数到栈中。</p><h3 id="lua_pushlightuserdata" tabindex="-1">lua_pushlightuserdata <a class="header-anchor" href="#lua_pushlightuserdata" aria-label="Permalink to &quot;lua_pushlightuserdata {#lua_pushlightuserdata}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushlightuserdata (lua_State *L, void *p);</pre><p>压入一个 light userdata 到栈中。</p><p>userdata 在Lua中表示一个C值。一个 <em>light userdata</em> 表示一个 *void 类型的指针。它是个值（和 number 一样）：你不需要专门创建它，它没有独立的元表并且不会被GC清理（因为它没有经历创建的过程）。任何 light userdata 之间，只要它们指向相同的C地址，那么它们就是相等的。</p><h3 id="lua_pushliteral" tabindex="-1">lua_pushliteral <a class="header-anchor" href="#lua_pushliteral" aria-label="Permalink to &quot;lua_pushliteral {#lua_pushliteral}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>const char *lua_pushliteral (lua_State *L, const char *s);</pre><p>这个宏等效于<a href="#lua_pushstring">lua_pushstring</a>，但只应该在 s 是一个字面量时使用。</p><h3 id="lua_pushlstring" tabindex="-1">lua_pushlstring <a class="header-anchor" href="#lua_pushlstring" aria-label="Permalink to &quot;lua_pushlstring {#lua_pushlstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>const char *lua_pushlstring (lua_State *L, const char *s, size_t len);</pre><p>将一个指向长度为 len 的字符串的指针 s 压入到栈中。Lua将新建或重用所给字符串的拷贝，所以 s 所指向的内存可以在函数返回后立刻释放或者继续复用。这个字符串可以包含任何二进制数据，包括嵌入的零值。</p><p>返回一个指向此字符串的内部拷贝的指针（参见<a href="/lua5.4-manual-zh/4.1.3.html">4.1.3</a>）。</p><h3 id="lua_pushnil" tabindex="-1">lua_pushnil <a class="header-anchor" href="#lua_pushnil" aria-label="Permalink to &quot;lua_pushnil {#lua_pushnil}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushnil (lua_State *L);</pre><p>将压入一个<strong>nil</strong>值到栈中。</p><h3 id="lua_pushnumber" tabindex="-1">lua_pushnumber <a class="header-anchor" href="#lua_pushnumber" aria-label="Permalink to &quot;lua_pushnumber {#lua_pushnumber}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre><p>压入一个值为 n 的浮点数到栈中。</p><h3 id="lua_pushstring" tabindex="-1">lua_pushstring <a class="header-anchor" href="#lua_pushstring" aria-label="Permalink to &quot;lua_pushstring {#lua_pushstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>m</em>]</span></p><pre>const char *lua_pushstring (lua_State *L, const char *s);</pre><p>将一个以零为终止符的字符串指针 s 压入到栈中。Lua将新建或重用所给字符串的拷贝，所以 s 所指向的内存可以在函数返回后立刻释放或者继续复用。</p><p>返回一个指向此字符串的内部拷贝的指针（参见<a href="/lua5.4-manual-zh/4.1.3.html">4.1.3</a>）。</p><p>如果 s 为 NULL ，则会将<strong>nil</strong>压入栈中并返回 NULL 。</p><h3 id="lua_pushthread" tabindex="-1">lua_pushthread <a class="header-anchor" href="#lua_pushthread" aria-label="Permalink to &quot;lua_pushthread {#lua_pushthread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>int lua_pushthread (lua_State *L);</pre><p>将 L 所表示的Lua线程压入到栈中。如果这个状态机的Lua线程是主线程则会返回1。</p><h3 id="lua_pushvalue" tabindex="-1">lua_pushvalue <a class="header-anchor" href="#lua_pushvalue" aria-label="Permalink to &quot;lua_pushvalue {#lua_pushvalue}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>void lua_pushvalue (lua_State *L, int index);</pre><p>拷贝给出索引处的值，并将其压入栈中。</p><h3 id="lua_pushvfstring" tabindex="-1">lua_pushvfstring <a class="header-anchor" href="#lua_pushvfstring" aria-label="Permalink to &quot;lua_pushvfstring {#lua_pushvfstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>v</em>]</span></p><pre>const char *lua_pushvfstring (lua_State *L,
                              const char *fmt,
                              va_list argp);</pre><p>等效于<a href="#lua_pushfstring">lua_pushfstring</a>，不同在于它最后一个参数类型是 va_list 而不是可变参。</p><h3 id="lua_rawequal" tabindex="-1">lua_rawequal <a class="header-anchor" href="#lua_rawequal" aria-label="Permalink to &quot;lua_rawequal {#lua_rawequal}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_rawequal (lua_State *L, int index1, int index2);</pre><p>当两个值直接相等时（即用不着调用元函数 __eq 来判断）会返回1。否则返回0。如果两者之间有任何的非法索引也会返回0。</p><h3 id="lua_rawget" tabindex="-1">lua_rawget <a class="header-anchor" href="#lua_rawget" aria-label="Permalink to &quot;lua_rawget {#lua_rawget}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +1, <em>-</em>]</span></p><pre>int lua_rawget (lua_State *L, int index);</pre><p>和<a href="#lua_gettable">lua_gettable</a>类似，但是执行的是直接访问（即不通过元函数访问）。索引处的值必须是个表。</p><h3 id="lua_rawgeti" tabindex="-1">lua_rawgeti <a class="header-anchor" href="#lua_rawgeti" aria-label="Permalink to &quot;lua_rawgeti {#lua_rawgeti}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>int lua_rawgeti (lua_State *L, int index, lua_Integer n);</pre><p>将 t[n] 的值压入栈中，这里的 t 为给出索引处的表。这也是直接访问的，即不使用元值 ___index 。</p><p>返回值为这个值的类型。</p><h3 id="lua_rawgetp" tabindex="-1">lua_rawgetp <a class="header-anchor" href="#lua_rawgetp" aria-label="Permalink to &quot;lua_rawgetp {#lua_rawgetp}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>int lua_rawgetp (lua_State *L, int index, const void *p);</pre><p>将 t[k] 的值压入栈中，这里的 t 为给出索引处的表，且 k 为表示指针 p 的一个 light userdata 。这也是直接访问的，即不使用元值 ___index 。</p><p>返回值为这个值的类型。</p><h3 id="lua_rawlen" tabindex="-1">lua_rawlen <a class="header-anchor" href="#lua_rawlen" aria-label="Permalink to &quot;lua_rawlen {#lua_rawlen}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Unsigned lua_rawlen (lua_State *L, int index);</pre><p>返回索引处值的“直接长度”：对于字符串，就是其字符串长度；对于表，就是执行取长操作符（&#39;#&#39;）的结果，但是不会调用元函数；对于 userdata，就是 userdata 关联的内存块大小。对于其他的值，此调用都返回0。</p><h3 id="lua_rawset" tabindex="-1">lua_rawset <a class="header-anchor" href="#lua_rawset" aria-label="Permalink to &quot;lua_rawset {#lua_rawset}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-2, +0, <em>m</em>]</span></p><pre>void lua_rawset (lua_State *L, int index);</pre><p>类似于<a href="#lua_settable">lua_settable</a>，但执行的是直接赋值（即不调用元函数）。索引处的值必须是一个表。</p><h3 id="lua_rawseti" tabindex="-1">lua_rawseti <a class="header-anchor" href="#lua_rawseti" aria-label="Permalink to &quot;lua_rawseti {#lua_rawseti}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>m</em>]</span></p><pre>void lua_rawseti (lua_State *L, int index, lua_Integer i);</pre><p>等效于执行 t[i] = v ，这里的 t 是索引处的表，v 是放在栈顶上的值。</p><p>此函数将值从栈上弹出。此处是直接赋值，即不会调用元值 __newindex 。</p><h3 id="lua_rawsetp" tabindex="-1">lua_rawsetp <a class="header-anchor" href="#lua_rawsetp" aria-label="Permalink to &quot;lua_rawsetp {#lua_rawsetp}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>m</em>]</span></p><pre>void lua_rawsetp (lua_State *L, int index, const void *p);</pre><p>等效于执行 t[p] = v ，这里的 t 是索引处的表，p 是转换后的 light userdata，且 v 是处于栈顶上的值。</p><p>此函数将值从栈上弹出。此处是直接赋值，即不会调用元值 __newindex 。</p><h3 id="lua_Reader" tabindex="-1">lua_Reader <a class="header-anchor" href="#lua_Reader" aria-label="Permalink to &quot;lua_Reader {#lua_Reader}&quot;">​</a></h3><pre>typedef const char * (*lua_Reader) (lua_State *L,
                                    void *data,
                                    size_t *size);</pre><p>用于<a href="#lua_load">lua_load</a>的 reader 函数。每当<a href="#lua_load">lua_load</a>需要代码块中的下一小块时，其会调用 reader，并接着传递参数 data 。这个 reader 必须返回指向代码块的新部分的指针，并且将 *size 设为这块内存的大小。这块内存必须直到下一次调用 reader 前都存在。为了表示代码块结束了，reader 必须返回 NULL 并将 *size 设为零。reader函数可以返回任意长度大于0的块。</p><h3 id="lua_register" tabindex="-1">lua_register <a class="header-anchor" href="#lua_register" aria-label="Permalink to &quot;lua_register {#lua_register}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>e</em>]</span></p><pre>void lua_register (lua_State *L, const char *name, lua_CFunction f);</pre><p>将全局变量 name 的值设为给出的C函数。这个宏是这样定义的：</p><div class="language-C vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">C</span><pre class="shiki shiki-themes github-light github-dark vp-code"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">#define</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> lua_register</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">L</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">n</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">f</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">        (</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_pushcfunction</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, f), </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">lua_setglobal</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(L, n))</span></span></code></pre></div><h3 id="lua_remove" tabindex="-1">lua_remove <a class="header-anchor" href="#lua_remove" aria-label="Permalink to &quot;lua_remove {#lua_remove}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>-</em>]</span></p><pre>void lua_remove (lua_State *L, int index);</pre><p>从栈上移除给出的有效索引的元素，空出来的位置由上边的元素依次下移填充。此函数不可以用虚拟索引调用，因为虚拟索引并不实际存在于栈上。</p><h3 id="lua_replace" tabindex="-1">lua_replace <a class="header-anchor" href="#lua_replace" aria-label="Permalink to &quot;lua_replace {#lua_replace}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>-</em>]</span></p><pre>void lua_replace (lua_State *L, int index);</pre><p>将栈顶的值移动到给出索引的位置（原文为 moves，但其实这个栈顶的元素还在），但是不下移任何元素（于是就替换了索引处的值），然后弹出栈顶的值。</p><h3 id="lua_resetthread" tabindex="-1">lua_resetthread <a class="header-anchor" href="#lua_resetthread" aria-label="Permalink to &quot;lua_resetthread {#lua_resetthread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +?, <em>-</em>]</span></p><pre>int lua_resetthread (lua_State *L);</pre><p>此函数已废弃；其等效于 from 参数为 NULL 的<a href="#lua_closethread">lua_closethread</a>调用。</p><h3 id="lua_resume" tabindex="-1">lua_resume <a class="header-anchor" href="#lua_resume" aria-label="Permalink to &quot;lua_resume {#lua_resume}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-？, +?, <em>-</em>]</span></p><pre>int lua_resume (lua_State *L, lua_State *from, int nargs,
                          int *nresults);</pre><p>开始或重启给定的Lua线程所指的协程 L 。（本质上是一回事）</p><p>如需启动一个协程，你必须将主函数和其所有参数都压入到这个Lua线程的空栈中。然后你再调用<a href="#lua_resume">lua_resume</a>，其参数 nargs 为主函数的参数数量。此调用会在协程执行完成或者被挂起时返回。当它返回时，由<a href="#lua_yield">lua_yield</a>或主函数返回的值会被放到栈顶上，*nresult 会变更为这些返回值的数量。当协程让出时<a href="#lua_resume">lua_resume</a>会返回<a href="/lua5.4-manual-zh/4.4.1.html">LUA_YIELD</a>，如果协程执行完成并未发生任何错误则返回<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>。在发生错误的情况下，错误对象会被放在协程L的栈顶中（而不是执行这个协程的主体线程）。</p><p>如需重启一个协程，你必须把在栈上的 *nresults 个让出返回值移除，将结果值压入栈中以传递给让出的地方，然后再调用<a href="#lua_resume">lua_resume</a>。</p><p>参数 from 表示执行重启的协程 L 的主体，其也是一个协程。如果不存在这样的协程，此参数可以是 NULL。</p><h3 id="lua_rotate" tabindex="-1">lua_rotate <a class="header-anchor" href="#lua_rotate" aria-label="Permalink to &quot;lua_rotate {#lua_rotate}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void lua_rotate (lua_State *L, int idx, int n);</pre><p>旋转/回绕给定索引处到栈顶之间的元素。当 n 是正数时，这些元素会向顶部方向旋转 n 个位置；如果是一个负值 -n ，那么会向栈底方向旋转 n 个位置。n 的绝对值不能大于需要旋转的元素数量。不可以使用虚拟索引来调用这个函数，因为虚拟函数实际上并不存在于栈上。</p><h3 id="lua_setallocf" tabindex="-1">lua_setallocf <a class="header-anchor" href="#lua_setallocf" aria-label="Permalink to &quot;lua_setallocf {#lua_setallocf}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);</pre><p>将内存分配函数改为 f 并带上用户数据 ud。</p><h3 id="lua_setfield" tabindex="-1">lua_setfield <a class="header-anchor" href="#lua_setfield" aria-label="Permalink to &quot;lua_setfield {#lua_setfield}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>e</em>]</span></p><pre>void lua_setfield (lua_State *L, int index, const char *k);</pre><p>等效于执行 t[k] = v，这里的 t 为给定索引处的表，v 为栈顶上的值。</p><p>此函数会从栈上弹出这个值。和在Lua代码中一样，此函数可能会触发&quot;newindex&quot;事件对应的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。</p><h3 id="lua_setglobal" tabindex="-1">lua_setglobal <a class="header-anchor" href="#lua_setglobal" aria-label="Permalink to &quot;lua_setglobal {#lua_setglobal}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>e</em>]</span></p><pre>void lua_setglobal (lua_State *L, const char *name);</pre><p>从栈上弹出一个值并将其赋值到全局变量 name 中。</p><h3 id="lua_seti" tabindex="-1">lua_seti <a class="header-anchor" href="#lua_seti" aria-label="Permalink to &quot;lua_seti {#lua_seti}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>e</em>]</span></p><pre>void lua_seti (lua_State *L, int index, lua_Integer n);</pre><p>等效于执行 t[n] = v，这里的 t 为给定索引处的表，v 为栈顶上的值。</p><p>此函数会从栈上弹出这个值。和在Lua代码中一样，此函数可能会触发&quot;newindex&quot;事件对应的元函数（参见<a href="/lua5.4-manual-zh/2.4.html">2.4</a>）。</p><h3 id="lua_setiuservalue" tabindex="-1">lua_setiuservalue <a class="header-anchor" href="#lua_setiuservalue" aria-label="Permalink to &quot;lua_setiuservalue {#lua_setiuservalue}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>-</em>]</span></p><pre>int lua_setiuservalue (lua_State *L, int index, int n);</pre><p>从栈上弹出一个值，将这个值设为给出索引处的 full userdata 的第 n 个 user value。当 userdata 中没有这个值时会返回0。</p><h3 id="lua_setmetatable" tabindex="-1">lua_setmetatable <a class="header-anchor" href="#lua_setmetatable" aria-label="Permalink to &quot;lua_setmetatable {#lua_setmetatable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-1, +0, <em>-</em>]</span></p><pre>int lua_setmetatable (lua_State *L, int index);</pre><p>从栈上弹出一个表或者<strong>nil</strong>，并将其设置为给出索引处的值的新元表。（<strong>nil</strong>意味着没有元表。）</p><p>（因为一些历史原因，此函数返回值类型为 int ，现在返回值已经无任何指示意义，总是会返回1。）</p><h3 id="lua_settable" tabindex="-1">lua_settable <a class="header-anchor" href="#lua_settable" aria-label="Permalink to &quot;lua_settable {#lua_settable}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-2, +0, <em>e</em>]</span></p><pre>void lua_settable (lua_State *L, int index);</pre><p>等效于执行 t[k] = v ，这里的 t 为给出索引处的值，v 是栈顶上的值，k 是紧跟在栈顶下边位置上的值。</p><p>此函数会从栈上弹出键和键值。和Lua代码中一样，此函数可能会触发 &quot;newindex&quot; 事件对应的元函数。</p><h3 id="lua_settop" tabindex="-1">lua_settop <a class="header-anchor" href="#lua_settop" aria-label="Permalink to &quot;lua_settop {#lua_settop}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-?, +?, <em>e</em>]</span></p><pre>void lua_settop (lua_State *L, int index);</pre><p>接受一个任意索引或者0，然后将栈顶增长或下降到这个索引的位置，即扩张或收缩栈的大小。如果新的栈顶位置大于原来的，那么新的元素都使用<strong>nil</strong>值填充。如果给出索引为0，那么所有栈元素都被移除。</p><p>此函数在移除的索引处为待关闭变量时可能会运行任意的代码（因为可能触发 __close 元函数）。</p><h3 id="lua_setwarnf" tabindex="-1">lua_setwarnf <a class="header-anchor" href="#lua_setwarnf" aria-label="Permalink to &quot;lua_setwarnf {#lua_setwarnf}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud);</pre><p>设置供Lua发出警告时使用的警告函数（参见<a href="#lua_WarnFunction">lua_WarnFunction</a>）。参数 ud 为每次调用此函数时需要传递给警告函数的特定数据。</p><h3 id="lua_State" tabindex="-1">lua_State <a class="header-anchor" href="#lua_State" aria-label="Permalink to &quot;lua_State {#lua_State}&quot;">​</a></h3><pre>typedef struct lua_State lua_State;</pre><p>该结构体并不透明，它指向一个Lua线程及（通过Lua线程）间接指向Lua解释器的一个完整的状态机。Lua库是完全可重入的，就是因为这个结构体没有使用全局变量。所有关于状态机的信息都可以通过这个结构体访问到。</p><p>库中的每个函数都需要将一个指向这个结构体的指针作为第一个参数传入，除了<a href="#lua_newstate">lua_newstate</a>，它是从头创建一个Lua状态机。</p><h3 id="lua_status" tabindex="-1">lua_status <a class="header-anchor" href="#lua_status" aria-label="Permalink to &quot;lua_status {#lua_status}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_status (lua_State *L);</pre><p>返回给出的Lua线程 L 的状态。</p><p>这个状态可以是表示正常的<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>、由<a href="#lua_resume">lua_resume</a>唤醒的Lua线程在执行时发生错误后的错误码、或是表示Lua线程已经被挂起的<a href="/lua5.4-manual-zh/4.4.1.html">LUA_YIELD</a>。</p><p>你只能在<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>状态中的线程中调用这个函数。你可以唤醒处在<a href="/lua5.4-manual-zh/4.4.1.html">LUA_OK</a>状态（会启动新协程）或<a href="/lua5.4-manual-zh/4.4.1.html">LUA_YIELD</a>状态（会唤醒协程）下的线程。</p><h3 id="lua_stringtonumber" tabindex="-1">lua_stringtonumber <a class="header-anchor" href="#lua_stringtonumber" aria-label="Permalink to &quot;lua_stringtonumber {#lua_stringtonumber}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +1, <em>-</em>]</span></p><pre>size_t lua_stringtonumber (lua_State *L, const char *s);</pre><p>将以零为终止符的字符串 s 转换为一个 number ，并将其压入到栈中，然后返回字符串的完整大小——即长度加一。根据Lua中的词法转换，此转换的结果可能是整数或浮点数（参见<a href="/lua5.4-manual-zh/3.1.html">3.1</a>）。字符串前边或后边可以有空白字符或符号。如果字符串内容不是一个有效的数字，此函数会返回0且不会做压栈操作。（注意此返回结果可以作为布尔值使用，转换成功即为true。）</p><h3 id="lua_toboolean" tabindex="-1">lua_toboolean <a class="header-anchor" href="#lua_toboolean" aria-label="Permalink to &quot;lua_toboolean {#lua_toboolean}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_toboolean (lua_State *L, int index);</pre><p>将给定索引处的Lua值转换为一个C布尔值（0或1）。和Lua中所有的真假值测试类似，<a href="#lua_toboolean">lua_toboolean</a>对于任何不同于<strong>false</strong>和<strong>nil</strong>的Lua值都返回true；否则返回false。（如果你只想接收Lua布尔值，可以使用<a href="#lua_isboolean">lua_isboolean</a>来探测类型。）</p><h3 id="lua_tocfunction" tabindex="-1">lua_tocfunction <a class="header-anchor" href="#lua_tocfunction" aria-label="Permalink to &quot;lua_tocfunction {#lua_tocfunction}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_CFunction lua_tocfunction (lua_State *L, int index);</pre><p>将给定索引处的Lua值转换为一个C函数，此值必须本就是C函数，否则返回NULL。</p><h3 id="lua_toclose" tabindex="-1">lua_toclose <a class="header-anchor" href="#lua_toclose" aria-label="Permalink to &quot;lua_toclose {#lua_toclose}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>m</em>]</span></p><pre>void lua_toclose (lua_State *L, int index);</pre><p>将在栈中的给定索引标记为待关闭槽位（参见<a href="/lua5.4-manual-zh/3.3.8.html">3.3.8</a>）。和Lua中的待关闭变量类似，栈上在该槽中的值将会在其超出作用域后被关闭。在这里的C函数上下文中，超出作用域指的是函数执行返回到Lua中了、或者发生了错误、或者通过<a href="#lua_settop">lua_settop</a>或<a href="#lua_pop">lua_pop</a>将该槽位从栈上移除了、或者调用了<a href="#lua_closeslot">lua_closeslot</a>。被标记位待关闭的槽位不应当使用除了<a href="#lua_settop">lua_settop</a>和<a href="#lua_pop">lua_pop</a>之外的任何API函数将其移除，除非提前通过<a href="#lua_closeslot">lua_closeslot</a>使之都失活了。</p><p>传入此函数的索引不应当等于或低于其他的待关闭槽位（原文没有解释原因，从源码看应当是为了保证析构的顺序）。</p><p>注意当 __close 元函数运行时，其无论是发生了错误还是正常返回，C调用栈都已经展开了，所以在调用函数时自动声明的C变量（例如某个缓冲区）都将超出作用域。</p><h3 id="lua_tointeger" tabindex="-1">lua_tointeger <a class="header-anchor" href="#lua_tointeger" aria-label="Permalink to &quot;lua_tointeger {#lua_tointeger}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Integer lua_tointeger (lua_State *L, int index);</pre><p>等效于 isnum 参数为NULL调用<a href="#lua_tointegerx">lua_tointegerx</a>。</p><h3 id="lua_tointegerx" tabindex="-1">lua_tointegerx <a class="header-anchor" href="#lua_tointegerx" aria-label="Permalink to &quot;lua_tointegerx {#lua_tointegerx}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);</pre><p>将给定索引处的Lua值转换为有符号整数类型<a href="#lua_Integer">lua_Integer</a>。给出的Lua值必须是整数、或是一个 number 、或是一个内容为可转换为整数的数字字符串（参见<a href="/lua5.4-manual-zh/3.4.3.html">3.4.3</a>）；否则<a href="#lua_tointegerx">lua_tointegerx</a>返回0。</p><p>如果参数 isnum 不为NULL，则会被赋值为一个布尔值以表明转换是否成功。</p><h3 id="lua_tolstring" tabindex="-1">lua_tolstring <a class="header-anchor" href="#lua_tolstring" aria-label="Permalink to &quot;lua_tolstring {#lua_tolstring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>m</em>]</span></p><pre>const char *lua_tolstring (lua_State *L, int index, size_t *len);</pre><p>将给定索引处的字符串转换为C字符串。如果 len 为NULL，其会将 *len 设为字符串长度。给出索引处的值必须是字符串或 number ，否则此函数返回NULL。如果是 number ，<a href="#lua_tolstring">lua_tolstring</a>会<em>将栈上的实际值改为字符串</em>。（通过<a href="#lua_next">lua_next</a>遍历表时对键使用<a href="#lua_tolstring">lua_tolstring</a>时会因为这里的改变而混淆遍历。）</p><p><a href="#lua_tolstring">lua_tolstring</a>返回值为在Lua状态机内部的一个字符串指针。此字符串总是以零（&#39;\\0&#39;）结尾（即C风格字符串），但是可以在其正文中包含其他的零。</p><h3 id="lua_tonumber" tabindex="-1">lua_tonumber <a class="header-anchor" href="#lua_tonumber" aria-label="Permalink to &quot;lua_tonumber {#lua_tonumber}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Number lua_tonumber (lua_State *L, int index);</pre><p>等效于 isnum 参数为NULL调用<a href="#lua_tonumberx">lua_tonumberx</a>。</p><h3 id="lua_tonumberx" tabindex="-1">lua_tonumberx <a class="header-anchor" href="#lua_tonumberx" aria-label="Permalink to &quot;lua_tonumberx {#lua_tonumberx}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);</pre><p>将给定索引处的Lua值转换为C类型<a href="#lua_Number">lua_Number</a>。给出的Lua值必须为一个 number 或一个可转换为number的字符串（参见<a href="/lua5.4-manual-zh/3.4.3.html">3.4.3</a>）；否则<a href="#lua_tonumberx">lua_tonumberx</a>返回0。</p><p>如果参数 isnum 不为NULL，则会被赋值为一个布尔值以表明操作是否成功。</p><h3 id="lua_topointer" tabindex="-1">lua_topointer <a class="header-anchor" href="#lua_topointer" aria-label="Permalink to &quot;lua_topointer {#lua_topointer}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>const void *lua_topointer (lua_State *L, int index);</pre><p>将给定索引处的Lua值转换为一个通用C指针（void*）。给出的值必须为 userdata、表、Lua线程、字符串或函数中的一种；否则<a href="#lua_topointer">lua_topointer</a>将返回 NULL。不同的对象会得到不同的指针。并且无法将指针转换为原始值。</p><p>通常此函数只用于哈希和调试信息中。</p><h3 id="lua_tostring" tabindex="-1">lua_tostring <a class="header-anchor" href="#lua_tostring" aria-label="Permalink to &quot;lua_tostring {#lua_tostring}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>m</em>]</span></p><pre>const char *lua_tostring (lua_State *L, int index);</pre><p>等效于 len 参数为NULL时调用<a href="#lua_tolstring">lua_tolstring</a>。</p><h3 id="lua_tothread" tabindex="-1">lua_tothread <a class="header-anchor" href="#lua_tothread" aria-label="Permalink to &quot;lua_tothread {#lua_tothread}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_State *lua_tothread (lua_State *L, int index);</pre><p>将给定索引处的值转换为Lua线程（用 <a href="#lua_State">lua_State</a>* 类型表示）。给出的值必须为一个Lua线程；否则此函数返回NULL。</p><h3 id="lua_touserdata" tabindex="-1">lua_touserdata <a class="header-anchor" href="#lua_touserdata" aria-label="Permalink to &quot;lua_touserdata {#lua_touserdata}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>void *lua_touserdata (lua_State *L, int index);</pre><p>如果给出索引处的值为一个 full userdata，则返回其内存块的地址。如果这个值为一个 light userdata，则直接返回值（light userdata 本就是个指针）。否则返回NULL。</p><h3 id="lua_type" tabindex="-1">lua_type <a class="header-anchor" href="#lua_type" aria-label="Permalink to &quot;lua_type {#lua_type}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_type (lua_State *L, int index);</pre><p>返回给定索引处值的类型，或者返回 LUA_TNONE 表示无效但可接受的索引。由<a href="#lua_type">lua_type</a>返回的类型在源代码 lua.h 文件中定义：LUA_TNIL、LUA_TNUMBER、LUA_TBOOLEAN、LUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA、LUA_TTHREAD、以及 LUA_TLIGHTUSERDATA 。</p><h3 id="lua_typename" tabindex="-1">lua_typename <a class="header-anchor" href="#lua_typename" aria-label="Permalink to &quot;lua_typename {#lua_typename}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>const char *lua_typename (lua_State *L, int tp);</pre><p>返回类型值 tp 对应的类型名，其必须是可以由<a href="#lua_type">lua_type</a>返回的值。</p><h3 id="lua_Unsigned" tabindex="-1">lua_Unsigned <a class="header-anchor" href="#lua_Unsigned" aria-label="Permalink to &quot;lua_Unsigned {#lua_Unsigned}&quot;">​</a></h3><pre>typedef ... lua_Unsigned;</pre><p><a href="#lua_integer">lua_Integer</a>的无符号版本。</p><h3 id="lua_upvalueindex" tabindex="-1">lua_upvalueindex <a class="header-anchor" href="#lua_upvalueindex" aria-label="Permalink to &quot;lua_upvalueindex {#lua_upvalueindex}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>int lua_upvalueindex (int i);</pre><p>返回此刻在运行的函数的第 i 个上值的虚拟索引（参见<a href="/lua5.4-manual-zh/4.2.html">4.2</a>）。i 必须在区间[1, 256]内。</p><h3 id="lua_version" tabindex="-1">lua_version <a class="header-anchor" href="#lua_version" aria-label="Permalink to &quot;lua_version {#lua_version}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-0, +0, <em>-</em>]</span></p><pre>lua_Number lua_version (lua_State *L);</pre><p>返回Lua版本。</p><h3 id="lua_WarnFunction" tabindex="-1">lua_WarnFunction <a class="header-anchor" href="#lua_WarnFunction" aria-label="Permalink to &quot;lua_WarnFunction {#lua_WarnFunction}&quot;">​</a></h3><pre>typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);</pre><p>警告函数的类型，由Lua发出警告时调用。第一个参数是由<a href="#lua_setwarnf">lua_setwarnf</a>设置的一个不透明指针。第二个参数是警告消息。第三个参数是个布尔值，用以表示是否会在下一次调用时继续重复这个警告消息。</p><p>关于警告的更多细节请参见<a href="#warn-msg1">warn</a>。</p><h3 id="lua_Writer" tabindex="-1">lua_Writer <a class="header-anchor" href="#lua_Writer" aria-label="Permalink to &quot;lua_Writer {#lua_Writer}&quot;">​</a></h3><pre>typedef int (*lua_Writer) (lua_State *L,
                           const void* p,
                           size_t sz,
                           void* ud);</pre><p>由<a href="#lua_dump">lua_dump</a>使用的写入函数。每次<a href="#lua_dump">lua_dump</a>需要读到代码块中的下一部分时都会调用它，调用时传入写入缓冲区（p）、大小（sz）以及提供给<a href="#lua_dump">lua_dump</a>的参数（ud）。</p><p>此函数会返回一个错误码：0意味着没有错误；其他的值意味着有错误且在下次调用前停止<a href="#lua_dump">lua_dump</a>。</p><h3 id="lua_xmove" tabindex="-1">lua_xmove <a class="header-anchor" href="#lua_xmove" aria-label="Permalink to &quot;lua_xmove {#lua_xmove}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-?, +?, <em>-</em>]</span></p><pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre><p>在同一个状态机中的不同Lua线程间交换值。</p><p>此函数会从 from 的栈上弹出n个值，并将其压入到 to 的栈中。</p><h3 id="lua_yield" tabindex="-1">lua_yield <a class="header-anchor" href="#lua_yield" aria-label="Permalink to &quot;lua_yield {#lua_yield}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-?, +?, <em>v</em>]</span></p><pre>int lua_yield (lua_State *L, int nresults);</pre><p>此函数等效于<a href="#lua_yieldk">lua_yieldk</a>，但是它没有延续函数（参见<a href="/lua5.4-manual-zh/4.5.html">4.5</a>）。因此，当唤醒Lua线程时，其会从之前调用<a href="#lua_yield">lua_yield</a>的地方开始执行。为避免意外，此函数应当在尾调用中使用。</p><h3 id="lua_yieldk" tabindex="-1">lua_yieldk <a class="header-anchor" href="#lua_yieldk" aria-label="Permalink to &quot;lua_yieldk {#lua_yieldk}&quot;">​</a></h3><p><span style="color:gray;float:right;font-size:small;">[-?, +?, <em>v</em>]</span></p><pre>int lua_yieldk (lua_State *L,
                int nresults,
                lua_KContext ctx,
                lua_KFunction k);</pre><p>让出一个协程（Lua线程）。</p><p>当C函数中调用<a href="#lua_yieldk">lua_yieldk</a>时，正在运行的协程会被挂起，通过调用<a href="#lua_resume">lua_resume</a>可以启动这个协程并继续返回。参数 nresults 表示当使用 lua_resume唤醒是将会从栈上返回多少个值。</p><p>当协程被再次唤醒，Lua会调用给出的延续函数 k 以在C函数中让出后继续执行（参见<a href="/lua5.4-manual-zh/4.5.html">4.5</a>）。这个延续函数会接收和之前的函数相同的栈，并将 n 个结果替换传递给 <a href="#lua_resume">lua_resume</a>。此外，延续函数还会接收由<a href="#lua_yieldk">lua_yieldk</a>传递的值 ctx 。</p><p>通常这个函数不会返回；当协程最终被恢复时，它会继续执行延续函数。然而有一种特殊情况：当其在行内或计数 hook 中被调用时（参见<a href="/lua5.4-manual-zh/4.7.html">4.7</a>）。在这种情况下，<a href="#lua_yieldk">lua_yieldk</a>应当不使用延续函数（索性使用<a href="#lua_yield">lua_yield</a>）且无结果返回，hook 也应当在此函数调用后立刻返回。Lua会让出，并当其再次唤醒时将继续执行并触发 hook 的函数。</p><p>当其由一个Lua线程中的一个挂起的C调用且没有延续函数时（被称为C调用边界），此函数可能会抛出错误，或者在一个无法在运行时挂起的Lua线程中调用时（通常是Lua主线程）。</p>`,568),n=[i];function r(u,p,h,o,_,d){return e(),l("div",null,n)}const c=a(s,[["render",r]]);export{k as __pageData,c as default};
