常见的陷阱
无法加载文件
第一个可能的错误是无法加载库。在这种情况下,通常会引发 OSError。
这是因为该文件不存在(或 OS 无法找到):
>>> cdll.LoadLibrary("foobar.so")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/__init__.py", line 425, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python3.5/ctypes/__init__.py", line 347, in __init__
self._handle = _dlopen(self._name, mode)
OSError: foobar.so: cannot open shared object file: No such file or directory
正如你所看到的,错误很明显且非常具有指示性。
第二个原因是找到了文件,但格式不正确。
>>> cdll.LoadLibrary("libc.so")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/__init__.py", line 425, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python3.5/ctypes/__init__.py", line 347, in __init__
self._handle = _dlopen(self._name, mode)
OSError: /usr/lib/i386-linux-gnu/libc.so: invalid ELF header
在这种情况下,文件是脚本文件而不是 .so
文件。尝试在 Linux 机器上打开 .dll
文件或在 32 位 python 解释器上打开 64 位文件时,也可能发生这种情况。正如你所看到的,在这种情况下,错误更加模糊,需要进行一些挖掘。
无法访问功能
假设我们成功加载了 .so
文件,那么我们需要访问我们的函数,就像我们在第一个例子中所做的那样。
当使用不存在的函数时,会引发 AttributeError
:
>>> libc.foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.5/ctypes/__init__.py", line 360, in __getattr__
func = self.__getitem__(name)
File "/usr/lib/python3.5/ctypes/__init__.py", line 365, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/i386-linux-gnu/libc.so.6: undefined symbol: foo