代码之家  ›  专栏  ›  技术社区  ›  Jens

Lua:为回调函数添加参数

  •  1
  • Jens  · 技术社区  · 8 年前

    短篇故事:如何在Lua中将参数传递给回调函数?

    长话短说:

    我正在开发带有NodeMCU固件的ESP8266。本质上,我打算构建一个破折号按钮,每个节点有多个按钮。我这样做是考虑到GPIO引脚的中断可能性。

    然而,如何将参数传递给回调函数似乎没有很好的文档记录。在我的情况下,我想知道中断来自哪个引脚。这就是我想到的。除引脚的值外,它正在工作,当被触发时,引脚的值似乎重置为初始化值1。

      -- Have an area to hold all pins to query (in testing only one)
    
      buttonPins = { 5 }
      direction="up"
    
      armAllButtons()
    
      function armAllButtons()
        for i,v in ipairs(buttonPins)
        do
            armButton(v)
        end
      end
    
    
      function armButton(buttonPin)
        print("Arming pin "..buttonPin.." for button presses.")
    
        gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
        gpio.trig(buttonPin, direction, function (buttonPin) notifyButtonPressed(buttonPin) end)
    
        print("Waiting for button press on "..buttonPin.."...")
      end
    
      function notifyButtonPressed(buttonPin)
        print("Button at pin "..buttonPin.." pressed.")
    
        --rearm the pins for interrupts
        armButton(buttonPin)
      end
    

    然而,从内部 notifyButtonPressed() 功能、价值 buttonPin 按下时总是1,而不是我预期的5。我假设这可能是数字变量的初始化值。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Luiz Menezes    8 年前

    首先,您的代码根本不运行…按原样,它将抛出

    input:6: attempt to call a nil value (global 'armAllButtons')
    

    我将您的代码片段重新排列为:

      buttonPins = { 5 }
      direction="up"
    
      function armButton(buttonPin)
        print("Arming pin "..buttonPin.." for button presses.")
    
        gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
        gpio.trig(buttonPin, direction, function (buttonPin) --notifyButtonPressed(buttonPin) end)
    
        print("Waiting for button press on "..buttonPin.."...")
      end
    
      function notifyButtonPressed(buttonPin)
        print("Button at pin "..buttonPin.." pressed.")
    
        --rearm the pins for interrupts
        armButton(buttonPin)
      end
    
      function armAllButtons()
        for i,v in ipairs(buttonPins)
        do
            armButton(v)
        end
      end
    
    armAllButtons()
    

    它输出:

    Arming pin 5 for button presses.
    Waiting for button press on 5...
    

    为了使回调能够完美地工作,您必须为每个按钮传递不同的函数,而不是尝试将参数传递给函数…请尝试以下操作:

      buttonPins = { 5 }
      direction="up"
    
      function armButton(buttonPin)
        print("Arming pin "..buttonPin.." for button presses.")
    
        gpio.mode(buttonPin,gpio.INT,gpio.FLOAT)
        gpio.trig(
          buttonPin, 
          direction, 
          function ()
            notifyButtonPressed(buttonPin) 
          end
        ) -- this should create a function for each button, and each function shall pass a different argument to notifyButtonPressed
    
        print("Waiting for button press on "..buttonPin.."...")
      end
    
      function notifyButtonPressed(buttonPin)
        print("Button at pin "..buttonPin.." pressed.")
    
        --rearm the pins for interrupts
        armButton(buttonPin)
      end
    
      function armAllButtons()
        for i,v in ipairs(buttonPins)
        do
            armButton(v)
        end
      end
    
    armAllButtons()