2011-12-02 18 views
5

Tôi có một dự án python dựa trên một số tệp lua, một trong số đó yêu cầu 'socket'. Tôi nhận được một lỗi tải socket.core "biểu tượng không xác định: lua_getmetatable" khi tôi cố gắng yêu cầu rằng tập tin lua từ python 2,7.Lỗi liên kết Lunatic Python lua.require ('socket') -> undefined symbol: lua_getmetatable

người mô phỏng đơn giả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 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 

Tôi đang sử dụng một recent Lunatic Python branch nơi tôi dọn dẹp những lời cảnh báo Py_ssize_t, và liblua5.1-socket2 trên Ubuntu 11.04

tôi nhận được lỗi tương tự nếu tôi sử dụng chính mã nguồn lunatic-python và/hoặc nâng cấp lên luasocket 2.0.2.

chỉnh sửa: Điều gì gây ra lỗi này và cách khắc phục sự cố?

chỉnh sửa # 2: Đây là đầu ra của tòa nhà luasocket-2.0.2. Các làm mặc định không xây dựng unix.so, và tôi sửa nó để xây dựng mà cũng vì vậy tôi không trộn và kết hợp 2.0.0 với 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' 
+0

Câu hỏi là gì? ;) – 0xC0000022L

+1

Điều gì gây ra lỗi này và cách khắc phục? – RedCup

+0

Các ký hiệu không được xuất khẩu chính xác từ mô-đun 'lua' có thể được sử dụng trong mô-đun mà nó yêu cầu. Bạn cũng có thể đăng nhật ký của giai đoạn biên dịch, chủ yếu là phần liên kết cuối cùng không? –

Trả lời

6

Vấn đề không phải là ở luasocket, nhưng trong cách biểu tượng từ thư viện được chia sẻ được xử lý.

Vấn đề là trong khi lua.so (mô-đun Python) liên kết đến liblua5.1.so, các module chia sẻ nạp bởi require không có quyền truy cập vào những biểu tượng từ liblua5.1.so. Trên Mac OS X, nó hoạt động, bởi vì các biểu tượng từ dlopen được tải là RTLD_GLOBAL theo mặc định.

tôi đã thử nghiệm với điều chỉnh nguồn Lua (lua-5.1.4/src/loadlib.c:69), tuy nhiên nó không được, vì vào thời điểm require được gọi từ lua.so, những biểu tượng từ liblua5.1.so đã được nạp tại địa phương cho lua.so. Đây là lý do tại sao luasocket không nhìn thấy chúng.

May mắn thay, Python cho phép bạn thay đổi ngữ nghĩa dlopen bằng mô-đun sys. Điều này cho phép bạn bắt buộc tải các mô-đun với RTLD_GLOBAL, chính xác là những gì cần thiết. Hãy thử chạy mã sau và xem liệu mã có hoạt động cho bạn hay không:

$ 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 ... Cảm ơn lời giải thích tuyệt vời quá. Đối với những người tò mò, bạn có thể tìm hiểu thêm về ldload thông qua 'man ldload' và [tài liệu Python cho mô-đun sys] (http://docs.python.org/library/sys.html). sys.setdlopenflags (n) chỉ là unix. – RedCup

+0

Tôi đang chạy vào một vấn đề tương tự ngoại trừ trên mặt lua thay vì python. Tôi đã thử xây dựng lại một cách điên cuồng với '-export-dynamic' hy vọng rằng các ký hiệu phụ thuộc vào nó sẽ được hiển thị cho các mô-đun tiếp theo được tải sau - nó không hoạt động.Trong tò mò, tại sao vấn đề này không xảy ra trên cửa sổ? – greatwolf