Lua函数返回字符串,但调用函数得到nil

Posted

技术标签:

【中文标题】Lua函数返回字符串,但调用函数得到nil【英文标题】:Lua function returns string, but calling function gets nil 【发布时间】:2021-06-10 21:58:11 【问题描述】:

我正在为 Nodemcu (esp8266) Lua 编写一个函数,以从 UART(有人打字)构建命令字符串。当它完成捕获字符时,它应该将字符串返回给调用函数,但调用函数只会得到 nil。我是 Lua 新手,我错过了什么?

local function getcmd()

  local t =  
  local cmd
  
  -- Callback function
  uart.on("data", 0, function(data)
    
    if data~='\r' then
      --Echo input
      t[#t+1] = data
      uart.write(0,t[#t])

      -- BACKSPACE/DEL
      if t[#t] == '' then
        t[#t] = nil
        t[#t] = nil
      end

      -- NEED <TAB> handling here too

    else
      --Disables callback
      --uart.on("data")

      -- Print table, convert to string.
      for i = 1, #t do
        uart.write(0, t[i])
        if i==1 then
          cmd = tostring(t[i])
        else
          cmd = cmd .. tostring(t[i])
        end
      end
      t =  

      if cmd ~= nil then
        uart.write(0, "Before Return> "..cmd)
        -- type() String
        return cmd
      end
    end
  end,0)
end

local function config()

  local cmdstr

  -- Testing
  cmdstr = getcmd()
  print("func() "..getcmd())

  if cmdstr ~= nil then
    uart.write(0, cmdstr.."> ")
  end
end

【问题讨论】:

您调用了两次getcmd()。是故意的吗? 是的,只是测试一下绝望的尝试是否有区别。感谢您的观看。 return cmd 从回调(事件处理程序)返回字符串,而不是从getcmd()getcmd 立即返回,它不等待事件。您应该等到cmd 不是nil 后再打印。您可以实现check_if_cmd_ready() 并定期调用它。 啊,有道理,让我试一试,我会告诉你的。谢谢! 事件驱动编程可能有点令人沮丧。我尝试了一个 While 循环,崩溃了,并不感到惊讶。我最终做的不是从getcmd()返回,而是在我的缓冲区有cmd之后从它调用config(cmd)。我对在事件处理程序实际结束之前调用 config(cmd) 有点担心/困惑。我想我必须记住在调用另一个函数之前从 config() 返回,这样我就不会溢出堆栈。 @EgorSkriptunoff 谢谢。 【参考方案1】:

感谢 @EgorSkriptunoff 帮助我了解正在发生的事情。

以下是有效的代码(到目前为止)。我尝试的是围绕 getcmd() 内的事件处理程序的 While 循环。这会失败,因为它会停止执行所有让 wifi 等保持 ESP8266 运行的基本功能的后台事件,因此它会反复崩溃/重启。

我没有从 getcmd() 返回而是直接调用 config() 并将我在事件处理程序中收集的输入传递给它,如下所示:config(cmd)

潜在的问题是,事件处理程序仍在运行,因为它从未到达终点,如果我在调用另一个函数之前不从 config() 返回,这可能会导致一些堆栈/内存问题。

不管怎样,这里是目前有效的代码:

function getcmd()

  local t =  
  cmd=nil

    uart.on("data", 0, function(data)
      
      if data~='\r' then
        --Echo input
        t[#t+1] = data
        uart.write(0,t[#t])
  
        -- BACKSPACE/DEL
        if t[#t] == 'BS' then
          t[#t] = nil
          t[#t] = nil
        end
      else
        --uart.on("data")
  
        if #t ~= nil then
          uart.write(0,"\r\n"..#t.."\r\n")
        end
  
        for i = 1, #t do
          uart.write(0, t[i])
          if i==1 then
            cmd = tostring(t[i])
          else
            cmd = cmd .. tostring(t[i])
          end
        end
        t =  
        if cmd ~= nil then
          -- Calling config() here doesn't allow event handler on.uart() to end.
          config(cmd)
        end
      end
    end,0)

  end

------------------------------------------------------
function config(cmd)

  print("\r<<"..cmd..">>\r")
  
  -- Now parse cmd and return.
end

【讨论】:

以上是关于Lua函数返回字符串,但调用函数得到nil的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法将 lua 函数从 C++ 更改为 nil,例如 changefunction(thefunction) 并且在调用时变为 nil

Lua - C++ 集成:从 C++ 调用表中的函数

lua rawset函数怎么用

lua C API

lua函数调用

lua 栈最后调用的函数,用于看调试信息