当我尝试导入一个加载32位库的简单ctype模块时,我得到:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "simple_test.py", line 5, in <module>
_myLib = ctypes.CDLL(_path + _file)
File "/usr/lib/python2.7/ctypes/__init__.py", line 353, in __init__
self._handle = _dlopen(self._name, mode)
OSError: ../../bin/mylib.so: wrong ELF class: ELFCLASS32
也发生在python 3.3上。
这里的问题是我不想将我的lib重新编译为64位, 有没有办法让它发挥作用?
谢谢, 凯伦
答案 0 :(得分:2)
您根本无法将32位代码加载到64位应用程序中,反之亦然。您的选择是:
multiprocessing
以便允许64位解释器与32位解释器通信。前两个选项遇到问题,基于debian的发行版使用包管理器无法同时安装32位解释器和64位解释器(参见eryksun的评论)。 p>
重新编译库几乎肯定是更容易的选择,并且绝对不会遭受运行时开销。
如何编号(2)的示例。预先警告,如果您经常使用这些方法或使用大输入/输出,这将导致来回发送数据的高额开销。
# example using the standard c library
from subprocess import Popen, PIPE
from multiprocessing.managers import BaseManager
import atexit
p = Popen(["/path/to/32-bit/python", "/path/to/delegate.py"], stdout=PIPE)
atexit.register(p.terminate)
port = int(p.stdout.readline())
authkey = p.stdout.read()
m = BaseManager(address=("localhost", port), authkey=authkey)
m.connect()
# tell manager to expect an attribute called LibC
m.register("LibC")
# access and use libc
libc = m.LibC()
print(libc.abs(-2))
from multiprocessing.managers import BaseManager
from ctypes import c_int, cdll
from os import closerange, write
# setup library
libc = cdll.LoadLibrary("libc.so.6")
# tell ctypes how to call function
libc.abs.argtypes = c_int,
libc.abs.restype = c_int
# wrapper for access to the functions
class LibC:
abs = staticmethod(libc.abs)
# setup manager
manager = BaseManager(address=("localhost", 0))
manager.register("LibC", LibC)
server = manager.get_server()
# tell caller the port and auth key to access the manager with
write(1, str(server.address[1]).encode("ascii"))
write(1, b"\n")
write(1, server.authkey) # write raw authkey bytes
closerange(0, 3) # close stdin, stdout, stderr
server.serve_forever()
答案 1 :(得分:1)
您还可以使用(相对)新的MSL-LoadLib。
它基本上是Dunes用他的例子描述的,但是捆绑了一个python32,所以你不必处理它。