链接器错误 Lunatic Python lua.require('socket') ->未定义符号:lua_getmetatable [英] Linker Error Lunatic Python lua.require('socket') -> undefined symbol: lua_getmetatable
问题描述
我有一个依赖于一些 lua 文件的 python 项目,其中之一需要套接字".当我尝试从 python 2.7 中要求 lua 文件时,我在加载 socket.core未定义符号:lua_getmetatable"时遇到错误.
I have a python project that relies on some lua files, one of which requires 'socket'. I get an error loading socket.core "undefined symbol: lua_getmetatable" when I try to require that lua file from python 2.7.
简单的复制器:
$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import lua
>>> lua.require('socket')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Exception: error: error loading module 'socket.core' from file
'/usr/lib/lua/5.1/socket/core.so':
/usr/lib/lua/5.1/socket/core.so: undefined symbol: lua_getmetatable
我正在使用 最近的 Lunatic Python 分支,在那里我清理了 Py_ssize_t 警告和 liblua5.1-socket2 在 Ubuntu 11.04 上
I am using a recent Lunatic Python branch where I cleaned up the Py_ssize_t warnings, and liblua5.1-socket2 on Ubuntu 11.04
如果我使用主要的 lunatic-python 源代码和/或升级到 luasocket 2.0,我会遇到同样的错误.2.
I get the same error if I use the main lunatic-python source code and/or upgrade to luasocket 2.0.2.
导致此错误的原因是什么,我该如何解决?
edit: What is causing this error, and how do I fix it?
编辑 #2:这是构建 luasocket-2.0.2 的输出.默认的 make 没有构建 unix.so,我编辑它来构建它,所以我没有将 2.0.0 与 2.0.2 混合和匹配:
edit #2: Here is the output of building luasocket-2.0.2. The default make did not build unix.so, and I edited it to build that as well so I didn't mix and match 2.0.0 with 2.0.2:
$ make
cd src; make all
make[1]: Entering directory `/sandbox/luasocket/luasocket-2.0.2/src'
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o luasocket.o luasocket.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o timeout.o timeout.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o buffer.o buffer.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o io.o io.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o auxiliar.o auxiliar.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o options.o options.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o inet.o inet.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o tcp.o tcp.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o udp.o udp.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o except.o except.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o select.o select.c
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o usocket.o usocket.c
gcc -O -shared -fpic -o socket.so.2.0.2 luasocket.o timeout.o buffer.o io.o auxiliar.o options.o inet.o tcp.o udp.o except.o select.o usocket.o
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o mime.o mime.c
gcc -O -shared -fpic -o mime.so.1.0.2 mime.o
gcc -I/usr/include/lua5.1 -DLUASOCKET_DEBUG -pedantic -Wall -O2 -fpic -llua -c -o unix.o unix.c
gcc -O -shared -fpic -o unix.so buffer.o auxiliar.o options.o timeout.o io.o usocket.o unix.o
make[1]: Leaving directory `/sandbox/luasocket/luasocket-2.0.2/src'
推荐答案
问题不在于 luasocket
,而在于共享库中符号的处理方式.
The problem is not in luasocket
, but in the way symbols from shared libraries are handled.
问题是lua.so
(Python模块)链接到liblua5.1.so
,require
加载的共享模块> 无法访问 liblua5.1.so
中的符号.在 Mac OS X 上,这是有效的,因为 dlopen
中的符号默认加载为 RTLD_GLOBAL
.
The problem is that the while the lua.so
(Python module) links to liblua5.1.so
, shared modules loaded by require
do not have access to the symbols from liblua5.1.so
. On Mac OS X this works, because symbols from dlopen
are loaded as RTLD_GLOBAL
by default.
我已经尝试修改 Lua 源代码 (lua-5.1.4/src/loadlib.c:69
),但是它没有帮助,因为到时候 require
code>是从lua.so
调用的,liblua5.1.so
的符号已经在本地为lua.so
加载了.这就是 luasocket
看不到它们的原因.
I have experimented with modifying the Lua source (lua-5.1.4/src/loadlib.c:69
), however it does not help, because by the time require
is called from lua.so
, the symbols from liblua5.1.so
have already been loaded locally for lua.so
. This is why luasocket
does not see them.
幸运的是,Python 允许您使用 sys
模块更改 dlopen
语义.这允许您强制加载带有 RTLD_GLOBAL
的模块,这正是所需要的.尝试运行以下代码,看看它是否适合您:
Fortunately, Python allows you to change the dlopen
semantics using the sys
module. This allows you to force to load modules with RTLD_GLOBAL
, which is exactly what is needed. Try running the following code and see if it works for you:
$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys, DLFCN
>>> sys.setdlopenflags(DLFCN.RTLD_NOW | DLFCN.RTLD_GLOBAL)
>>> import lua
>>> lua.require("socket")
<Lua table at 0x22ccef0>
这篇关于链接器错误 Lunatic Python lua.require('socket') ->未定义符号:lua_getmetatable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!