2011-12-02 14 views
5

Bazı lua dosyalarına dayanan ve bunlardan biri 'soket' gerektiren bir python projem var. Ben python 2.7 lua dosyası gerektirmeye çalıştığınızda socket.core "undefined sembolü: lua_getmetatable" bir hata alıyorum.Linker Hatası Lunatic Python lua.require ('soket') -> tanımsız sembol: lua_getmetatable

Basit reproducer: Ben ana kullanırsanız

Ubuntu 11.04 üzerinde

$ 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 

Ben Py_ssize_t uyarıları temizledik nerede bir recent Lunatic Python branch kullanıyorum ve liblua5.1-socket2 aynı hatayı alıyorum lunatic-python kaynak kodu ve/veya luasocket 2.0.2'a yükseltme.

düzenleme: Bu hata neden oluyor ve nasıl düzeltebilirim?

düzenleme # 2: İşte binanın luasocket-2.0.2 çıktısı. Varsayılan yapmak unix.so inşa etmedi ve ben karıştırmak ve maç 2.0.0 2.0.2 ile vermedi bu yüzden de o inşa etmek düzenlendi:

$ 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' 
+0

Sorun nedir? ;) – 0xC0000022L

+1

Bu hataya neden oluyor ve nasıl düzeltebilirim? – RedCup

+0

Semboller, gerektirdiği modülde kullanılabilecek "lua" modülünden doğru şekilde dışa aktarılmaz. Derleme aşamasının, özellikle son bağlantı parçasının bir kaydını da gönderebilir misiniz? –

cevap

6

sorun luasocket değil, ama Bu şekilde paylaşılan kütüphanelerden gelen semboller ele alınır.

sorun ise require tarafından yüklenen liblua5.1.so, paylaşılan modülleri lua.so (Python modülü) bağlantılar liblua5.1.so gelen sembollerin erişimi kalmamasıdır. Mac OS X'te bu çalışır; çünkü dlopen arasındaki simgeler varsayılan olarak RTLD_GLOBAL olarak yüklenir.

nedeniyle requirelua.so çağrılır zaman, ancak yardımcı olmuyor, Lua kaynağını (lua-5.1.4/src/loadlib.c:69) modifiye ile denemişlerdir, liblua5.1.so gelen semboller zaten lua.so için lokal olarak yüklendi. Bu nedenle, luasocket bunları görmez.

Neyse ki Python, sys modülünü kullanarak dlopen semantiklerini değiştirmenize izin verir. Bu, tam olarak ihtiyaç duyulan, RTLD_GLOBAL ile modül yüklemeye zorlamanızı sağlar. Aşağıdaki kodu çalıştırmayı deneyin ve sizin için çalışıp çalışmadığını görün:

$ 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> 
+0

Wow hakkında şikâyette bulunduğundan ... Büyük açıklama için teşekkürler. Merak etmek gerekirse, ldload hakkında 'man ldload' ve [sys modülü için Python dokümanları] (http://docs.python.org/library/sys.html) üzerinden daha fazla bilgi edinebilirsiniz. sys.setdlopenflags (n) sadece unix'dir. – RedCup

+0

Ben python yerine lua tarafında dışında benzer bir sorun olarak koşuyorum. Daha sonra yüklenen sonraki modüller için göründüğü sembollerin görünür olmasını ümit ederek--portport-dynamic' ile yeniden doğmayı denedim - işe yaramadı.Merak etme, neden bu sorun pencerelerde gerçekleşmiyor? – greatwolf