36.6. dl-在共享库中调用 C 函数

从 2.6 版开始不推荐使用:Python 3 中已删除dl模块。请改用ctypes模块。

dl模块定义dlopen()函数的接口,该接口是 Unix 平台上用于处理动态链接库的最常用接口。它允许程序在这样的库中调用任意函数。

Warning

dl模块绕过 Python 类型系统和错误处理。如果使用不当,可能会导致分段错误,崩溃或其他不正确的行为。

Note

除非sizeof(int) == sizeof(long) == sizeof(char *),否则该模块将不起作用。如果不是这种情况,则将在导入时引发SystemError

dl模块定义以下Function:

  • dl. open(* name * [,* mode = RTLD_LAZY *])
    • 打开一个共享的对象文件,并返回一个句柄。模式表示后期绑定(RTLD_LAZY)或立即绑定(RTLD_NOW)。默认值为RTLD_LAZY。请注意,某些系统不支持RTLD_NOW

返回值为dlobject

dl模块定义以下常量:

  • dl. RTLD_LAZY

  • dl. RTLD_NOW

    • 用作open()的参数。请注意,在不支持立即绑定的系统上,此常数将不会出现在模块中。为了获得最大的可移植性,请使用hasattr()确定系统是否支持即时绑定。

dl模块定义以下异常:

  • exception dl. error
    • 动态加载和链接例程中发生错误时引发异常。

Example:

>>> import dl, time
>>> a=dl.open('/lib/libc.so.6')
>>> a.call('time'), time.time()
(929723914, 929723914.498)

该示例在 Debian GNU/Linux 系统上进行了try,并且很好地说明了使用此模块通常是一个不好的选择。

36.6.1. Dl 对象

如上面的open()返回的 Dl 对象具有以下方法:

  • dl. close ( )

    • 释放除内存之外的所有资源。
  • dl. sym(* name *)

    • 如果引用的共享对象中存在* name *函数的指针,则以数字形式返回它的指针,否则返回None。这在以下代码中很有用:
>>> if a.sym('time'):
...     a.call('time')
... else:
...     time.time()

(请注意,此函数将返回非零数字,因为* NULL *指针为零)

  • dl. call(* name * [,* arg1 * [,* arg2 ... *]])
    • 在引用的共享库中调用名为* name 的函数。参数必须是 Python 整数(将按原样传递),Python 字符串(将向其传递指针)或None(将以 NULL *传递)。请注意,字符串仅应以const char*的形式传递给函数,因为 Python 不会喜欢将其字符串变异。

最多必须有 10 个参数,未给出的参数将被视为None。该函数的返回值必须为 C long,这是一个 Python 整数。