2

可以嵌入 PyPy 使用新的 extern "Python" 样式 cffi 回调吗?PyPy 的文档仅显示旧式 cffi 回调,但 cffi 文档建议不要使用它们。PyPy 文档没有提及新样式回调,我无法让新样式回调工作。

嵌入 PyPy

Extern “Python”(新型回调)

# file "interface.py"

import cffi

# add new extern "Python" declaration
ffi = cffi.FFI() ffi.cdef('''
struct API {
    double (*add_numbers)(double x, double y);

    extern "Python" void add_numbers2(double, double);
}; ''')

# Better define callbacks at module scope, it's important to
# keep this object alive.
@ffi.callback("double (double, double)")
def add_numbers(x, y):
    return x + y

# new function
@ffi.def_extern()
def add_numbers2(x, y):
    return x + y


def fill_api(ptr):
    global api
    api = ffi.cast("struct API*", ptr)
    api.add_numbers = add_numbers

运行编译后的 C 时出错(C 的源代码与 PyPy 文档相同):

debug: OperationError:
debug: operator-type: CDefError
debug: operator-value: cannot parse "extern "Python" void add_numbers2(double, double);"
:6:5: before: extern
Error calling pypy_execute_source_ptr!
4

1 回答 1

2

“extern Python”现在并不真正打算用于嵌入情况,例如您所指的情况。为了很好地支持这种情况,cffi 的开发人员需要付出更多的努力(包括我 :-)。换句话说,未来的 cffi 版本应该提供一种替代方法来进行嵌入,比 CPython 和 PyPy 的自定义解决方案更简单(分别是“使用 CPython C API”和“遵循https://pypy.readthedocs.org/en/最新/embedding.html ")。它还应该提供一个单一的通用解决方案。然而,现在还没有完成。

您可以在 PyPy 文档的示例之上应用现有的(cffi 1.4)“extern Python”解决方案,但它需要一些重构——值得注意的是,该示例使用“in-line ABI 模式”,而“extern Python”仅适用于“离线 API 模式”。如果我们将https://pypy.readthedocs.org/en/latest/embedding.html视为描述纯粹的 ABI 模式方法,那么 usingffi.callback()仍然是 CFFI 中记录且唯一的方法。

更新: CFFI 1.5 完全支持以“extern Python”样式嵌入(http://cffi.readthedocs.org/en/latest/embedding.html)。它现在可以在 CPython 上使用。PyPy 需要主干版本(或 PyPy 4.1,应该在 2016 年 3 月或 4 月推出)。

于 2015-12-21T17:16:29.823 回答