[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: C and Lua modules
- From: Renato Maia <maia@...>
- Date: Thu, 29 Jul 2010 14:30:36 -0300
On 28/07/2010 22:39, Duck wrote:
I wish that Lua+C "combo-modules" wouldn't rely on loading the Lua
code
first, and would build the core code as an .so on its own.
I guess you're missing the actual problem. In fact, you can load
'socket.core' without any Lua code. For example (for sake of
simplicity I'm calling 'luaopen_socket_core' directly although it is
not the proper thing to do):
#include <lua.h>
#include <lauxlib.h>
#include <luasocket.h>
int main(int argc, char* argv[])
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_socket_core(L);
luaL_dostring(L,
"s = assert(socket.tcp())"
"assert(s:connect('www.lua.org', 80))"
"assert(s:send('Hello, Lua!\\n'))"
"print(s:receive())");
lua_close(L);
return 0;
}
On 28 Jul 2010, at 21:04, Tim Channon wrote:
The workaround for static I use is very simple. Delete references to
load core from the static included .lua sources, no problem because
statically it is already loaded.
The thing about LuaSocket that might get people confused is that the
'luaopen_socket_core' function does not actually load a 'socket.core'
module as it should. Instead, it loads part of the 'socket' module and
does not set the 'package.loaded["socket.core"]' to indicate this
module was loaded. Therefore, any later 'require "socket.core"' will
fail even though this module is actually "loaded".
To fix this you can do like Tim Channon suggested above and avoid any
'require "socket.core"' in your code or you can simply fix what
'luaopen_socket_core' did with something like:
package.loaded["socket.core"] = package.loaded["socket"]
Moreover, although the 'luaopen_socket_core' function does not load
the 'socket' module completely it sets the 'package.loaded["socket"]'
as if it does. This turns out that any following attempt to load the
rest of the 'socket' module using a 'require "socket"' will be in
vain. For example:
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "socket.core"
> require "socket"
> s=assert(socket.connect("www.lua.org", 80))
stdin:1: attempt to call field 'connect' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
To fix that, you can do something like the following before any
'require "socket"':
package.loaded["socket"] = nil
Or better yet you can fix both problems by changing LuaSocket. For
example:
-- src/luasocket.old 2010-07-29 13:47:32.000000000 -0300
+++ src/luasocket.c 2010-07-29 14:18:26.000000000 -0300
@@ -89,7 +89,7 @@
static int base_open(lua_State *L) {
if (socket_open()) {
/* export functions (and leave namespace table on top of
stack) */
- luaL_openlib(L, "socket", func, 0);
+ luaL_openlib(L, "socket.core", func, 0);
#ifdef LUASOCKET_DEBUG
lua_pushstring(L, "_DEBUG");
lua_pushboolean(L, 1);
--- src/socket.old 2010-07-29 14:10:07.000000000 -0300
+++ src/socket.lua 2010-07-29 14:19:13.000000000 -0300
@@ -11,6 +11,7 @@
local string = require("string")
local math = require("math")
local socket = require("socket.core")
+_G.socket = socket -- load this module in the same table of
'socket.core'
module("socket")
Most people never face these problems because they always call
'require "socket"' first and never invoke the 'luaopen_socket_core'
function directly, which is either available through the
'package.cpath' or carefully preloaded. Instead, this function is
called through a 'require "socket.core"' that will eventually set the
'package.loaded["socket.core"]' for it.
On 28 Jul 2010, at 22:32, Quae Quack wrote:
Could I put up the suggestion that the module adds nothing to the
global environment, but instead just returns the module? (that is, a
NULL argument to luaL_register)...
My impression is that 'luaopen_socket_core' creating a global 'socket'
table is not a problem in this particular case thus avoiding such
practice might not be the answer here.
--
Renato Maia
Computer Scientist
Tecgraf/PUC-Rio
__________________________
http://www.inf.puc-rio.br/~maia/