【问题标题】:Python, PyPy and CFFI: what am I supposed to use?Python、PyPy 和 CFFI:我应该使用什么?
【发布时间】:2015-12-12 18:53:29
【问题描述】:

我需要用 python 调用 C 库,经过一番考虑,似乎 CFFI 最适合这种工作。但是,到目前为止,如果我正确使用它,我会感到非常困惑,因为有些东西似乎只在 PyPy 上按预期工作,而另一些似乎只在 Python3 上工作(据我所知,PyPy 不支持) )。

这是 CFFI 文档中最基本的代码示例:

>>> from cffi import FFI
>>> ffi = FFI()
>>> ffi.cdef("""
...     int printf(const char *format, ...);   // copy-pasted from the man page
... """)
>>> C = ffi.dlopen(None)                     # loads the entire C namespace
>>> arg = ffi.new("char[]", "world")         # equivalent to C code: char arg[] = "world";
>>> C.printf("hi there, %s.\n", arg)         # call printf
hi there, world.
17                                           # this is the return value
>>>

使用 Python3 运行此代码时,我收到以下错误: TypeError: ctype 'char[]' 的初始化程序必须是字节或列表或元组,而不是 str

寻找错误时,我发现它是去年 1 月在 PyPy 中修复的问题。所以我看看这个东西是否与 PyPy 一起运行,它确实如此。万岁!

但是,已经在第二个示例中,我遇到了相反的问题:

# file "simple_example_build.py"

# Note: this particular example fails before version 1.0.2
# because it combines variadic function and ABI level.

from cffi import FFI

ffi = FFI()
ffi.set_source("_simple_example", None)
ffi.cdef("""
    int printf(const char *format, ...);
""")

if __name__ == "__main__":
    ffi.compile()

在 PyPy 中运行它会引发另一个错误:

AttributeError: 'FFI' object has no attribute 'set_source'

由于示例说明它不适用于旧版本,因此我检查了我的 CFFI 版本:1.2.1,一切正常。

最后我用 Python3 而不是 PyPy 运行第二个示例,谁会想到,它完全按照它应该做的那样做。

作为 Python 新手,现在我真的不知道我应该使用什么,以及为什么同一文档中的示例只能在不同版本的语言上运行。当然还有一个问题,我可能只是配置了一些错误(对于 Linux 来说也是新手),或者我应该完全使用另一个 python 版本。有人能解释一下吗?

【问题讨论】:

    标签: python-3.x pypy python-cffi


    【解决方案1】:

    使用 Python3 运行此代码时,出现以下错误:TypeError: initializer for ctype 'char[]' must be a bytes or list or tuple, not str

    是的,因为对于 Python 3,您需要使用“b”前缀来确保您正在处理字节。文档中的示例在下面清楚地说明了这一点。

    AttributeError: 'FFI' 对象没有属性 'set_source'

    这意味着你有一个旧版本的 PyPy。 CFFI 的版本不能在给定版本的 PyPy 中升级;你需要升级 PyPy 本身。检查您的特定 PyPy 附带的 CFFI 版本,如下所示:

    $ pypy
    Python 2.7.9 (295ee98b6928, May 31 2015, 07:29:04)
    [PyPy 2.6.0 with GCC 4.8.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>>> import cffi
    >>>> cffi.__version__
    '1.1.0'
    

    我很确定您使用的是旧版 CFFI 附带的旧版 PyPy,而不是 1.2.1。

    【讨论】:

    • >>>>“文档中的示例在下面清楚地说明了这一点。”谢谢。我现在觉得很傻。或者失明,也许。
    【解决方案2】:

    你可以修改如下:

    from cffi import FFI
    ffi = FFI()
    ffi.cdef("""int printf(const char *format, ...);""")
    C = ffi.dlopen(None)                     # loads the entire C namespace
    arg = ffi.new("char[]", b"world")         # equivalent to C code: char arg[]     = "world";
    C.printf(b"hi there, %s.\n", arg)         # call printf
    

    【讨论】:

      猜你喜欢
      • 2013-09-27
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 2016-03-27
      • 2010-12-19
      • 2018-06-26
      相关资源
      最近更新 更多