简体   繁体   中英

“attempt to call global 'tonumber' (a nil value)” in Lua, embedded (in VLC)

I use VLC media player 1.1.9 on Ubuntu 11.04. I'm trying to experiment with lua extensions for VLC; so I've added the file test.lua in ~/.local/share/vlc/lua/extensions/ , which has only these two lines:

fps="25.000"
frame_duration=1/tonumber(fps)

When I run vlc with verbose output for debugging, I get (edited to split on multiple lines:):

$ vlc --verbose 2
...
[0xa213874] lua generic warning: Error loading script 
 ~/.local/share/vlc/lua/extensions/test.lua: 
 .../.local/share/vlc/lua/extensions/test.lua:2:
  attempt to call global 'tonumber' (a nil value)
...

Now, as far as I know, tonumber as function is part of Lua5.1 proper ( Lua 5.1 Reference Manual: tonumber ) - and on my system:

$ locate --regex 'lua.*so.*' | head -4
/usr/lib/libipelua.so.7.0.10
/usr/lib/liblua5.1.so
/usr/lib/liblua5.1.so.0
/usr/lib/liblua5.1.so.0.0.0

... apparently I do have Lua 5.1 installed.

So, why do I get an error on using tonumber here - and how can I use this (and other) standard functions in a VLC lua extension properly?

Documentation is sparse for VLC Lua extensions to say the least but I did find an example in the github vlc repository here: https://github.com/videolan/vlc/blob/master/share/lua/extensions/VLSub.lua

Judging from that example it appears you need to supply some basic event functions for your addon for VLC to call into when certain events happen. Some of the obvious callback handlers I've noticed:

  • descriptor , this should return a table that contains fields describing your addon.
  • activate , this seems to get called when you activate it from view menubar.
  • deactivate , called when you deactivate the addon from view menubar.

plus a couple of other functions like close and input_change which you can guess what they're for.

From my brief testing done on VLC 2.0.8 under Win7 it appears VLC loads the lua extension using an empty sandbox environment. This is likely the reason you're getting nil for tonumber and I'm betting none of the other standard lua functions are accessible either when you try to perform computation at this global scope.

However, if I move that code into one of the event handling functions then all those standard functions are accessible again. For example:

function descriptor()
   return
   {
      title = "Test Ext";
      version = "0.1";
      author = "";
      shortdesc = "Testing Lua Extension";
      capabilities = {};
      description = "VLC Hello Test Addon";
   }
end

function activate()
  print "test activating"

  local fps = tonumber "25.000"
  local frame_duration = 1 / fps
  print(frame_duration)

  return true
end
-- ...

That prints out what you would expect in the console debug log. Now the documentation (what little there is) doesn't mention any of this but what's probably happening here is VLC is injecting the standard lua functions and vlc api table into the sandboxed environment when any of these event handlers get called. But during the extension loading phase, it is done in an empty sandbox environment which explains why all those lua function calls end up being nil when you try to use it at the outter most scope.

I recommend cloning the VLC source tree from github and then performing a grep on the C source that's embedding lua to see what VLC is really doing behind the scenes. Most of the relevant code will likely be here: https://github.com/videolan/vlc/tree/master/modules/lua

Probably some extension script installed in your system overwrites the function and the Lua interpreter instance is shared between all extension scripts, so you end up not being able to call the function if that script is called before yours.

As a quick workaround, Lua being dynamically typed, you can still do things like:

1 / "25.000"

and the string will be coerced to a number.

Alternatively, you can define a tonumber equivalent like:

string_to_num = function(s) return s + 0 end

This again relies on dynamic typing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM