奇怪的Python ctypes行为。始终加载m(数学)库

时间:2018-04-18 00:11:10

标签: python ctypes

有人可以向我解释为什么以下Python代码有效吗?

import ctypes
import ctypes.util

boblib = ctypes.cdll.LoadLibrary(ctypes.util.find_library("bob_is_your_uncle"))
boblib.cos.argtypes = [ctypes.c_double]
boblib.cos.restype = ctypes.c_double
print(boblib.cos(0)) # This prints out "1.0"

我1000%确定没有" bob_is_your_uncle"我的文件系统上的库。然而,似乎ctypes加载了m库。为什么会这样?

另外,如果我这样做:print(boblib),我明白了:

<CDLL 'None', handle 7f6a80f6d170 at 0x7f6a7f34d0b8>

CDLL 'None'是什么意思?

提前致谢。

PS:对我的两个Python解释器执行--versionPython 3.6.5rc1Python 2.7.14+。上面的代码在两个版本上都给出了相同的结果。我的操作系统是Debian(测试回购)。

1 个答案:

答案 0 :(得分:2)

它没有加载数学库。它似乎正在加载Python可执行文件本身,其中链接有cos

确实没有名为bob_is_your_uncle的库,因此find_library会返回None。 (这就是None来自你所看到的输出的地方。)

在Unix上,LoadLibrary逻辑有一个specific check,它将None名称转换为基础dlopen例程的空指针。 dlopen的空名称为special handling

  

如果 filename 为NULL,则返回的句柄用于主程序。

事实上,在Unix上,ctypes.pythonapicreated

pythonapi = PyDLL(None)

首先解释None处理的原因。您创建的CDLL对象几乎,如ctypes.pythonapi,除了它没有为函数调用保存GIL或检查异常(因为CDLL而不是PyDLL),所以它没用用于与实际的C Python API交互。