【问题标题】:Why does loading the libc shared library have "'LibraryLoader' object is not callable" error?为什么加载 libc 共享库会出现“'LibraryLoader' object is not callable”错误?
【发布时间】:2018-06-11 13:29:50
【问题描述】:

来自https://en.wikipedia.org/wiki/Foreign_function_interface

ctypes 模块可以从共享库/DLL 加载 C 函数 即时并在之间自动转换简单的数据类型 Python和C语义如下:

import ctypes
libc = ctypes.CDLL( '/lib/libc.so.6' )   # under Linux/Unix
t = libc.time(None)                      # equivalent C code: t = time(NULL)
print t

在 Lubuntu 18.04 上

$ whereis libc
libc: /usr/lib/x86_64-linux-gnu/libc.a /usr/lib/x86_64-linux-gnu/libc.so /usr/share/man/man7/libc.7.gz

$ locate libc.so
/lib/i386-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so

$ ls -l /usr/lib/x86_64-linux-gnu/libc.so
-rw-r--r-- 1 root root 298 Apr 16 16:14 /usr/lib/x86_64-linux-gnu/libc.so

我想知道为什么加载 libc 共享库会出现“'LibraryLoader' object is not callable”错误?

$ python3 --version
Python 3.6.5

$ python3

>>> import ctypes
>>> libc=ctypes.cdll("/usr/lib/x86_64-linux-gnu/libc.so")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'LibraryLoader' object is not callable


>>> libc=ctypes.cdll("/lib/x86_64-linux-gnu/libc.so.6")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'LibraryLoader' object is not callable


>>> libc=ctypes.cdll("/lib/i386-linux-gnu/libc.so.6")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'LibraryLoader' object is not callable

另见https://unix.stackexchange.com/questions/449107/what-differences-and-relations-are-between-the-various-libc-so

【问题讨论】:

    标签: python linux ctypes libc dynamic-loading


    【解决方案1】:

    您将小写 cdll(即 LibraryLoader)与大写 CDLL(共享库的构造函数)混淆了。

    此代码将按预期工作:

    libc = ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6")
    

    【讨论】:

    • 加载/lib/x86_64-linux-gnu/libc.so.6不是更好吗?否则 Python 脚本在运行时将需要 C 库开发包...
    • @StephenKitt 我认为这超出了问题的范围。这是关于如何正确加载库,而不是哪个是最好的。
    • 同意;我只是想降低复制意大利面的风险;-)(它会使答案与开始这一切的示例相对应)。
    • 谢谢。 LibraryLoader(例如cdll)和共享库的构造函数(例如CDLL)有什么区别?他们都可以做同样的事情吗?
    • @Tim 我不知道该说什么。这一切都在文档中进行了解释,所以我真的只能从那里重复信息:LibraryLoader 是一个允许您通过属性访问加载库的对象。 CDLL(连同WinDLL 和其他)是那些加载的库的类。基本上是cdll.foo == CDLL('foo')windll.foo == WinDLL('foo')
    猜你喜欢
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多