链接器错误Lunatic Python lua.require('socket')->未定义符号:lua_getmetatable [英] Linker Error Lunatic Python lua.require('socket') -> undefined symbol: lua_getmetatable

查看:60
本文介绍了链接器错误Lunatic Python lua.require('socket')->未定义符号:lua_getmetatable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个依赖于一些lua文件的python项目,其中一个文件需要"socket".尝试从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 Ubuntu 11.04上的.1-socket2

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:这是Building 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),但这无济于事,因为从lua.so调用require时,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆