概览

您所在的位置:网站首页 577团去哪里了 概览

概览

2023-05-05 11:44| 来源: 网络整理| 查看: 265

ABI 与 API¶

在二进制级别("ABI")访问C库充满了问题,特别是在非Windows平台上。

ABI级别最直接的缺点是调用函数需要通过非常通用的*libffi*库,这很慢(并且在非标准平台上并不总是完美测试)。 API模式改为编译直接调用目标函数的CPython C包装器。 它可以更快(并且比libffi工作得更好)。

更喜欢API模式的根本原因是 C库通常用于与C编译器一起使用。 你不应该做猜测结构中字段的位置。 上面的 "真实示例" 显示了CFFI如何使用C编译器: 此示例使用 set_source(..., "C source...") 而不是 dlopen()。 使用这种方法时, 我们的优点是我们可以在 cdef() 中的不同位置使用字面 "...",缺少的信息将在C编译器的帮助下完成。 CFFI会将其转换为单个C源文件,其中包含未经修改的"C源代码"部分,后跟一些"魔术"C语言代码和从 cdef() 派生的声明。 编译此C语言文件时,生成的C扩展模块将包含我们需要的所有信息- 或者C编译器将发出警告或错误,例如.如果我们错误地声明了某些函数的签名。

请注意 set_source() 中的"C source" 部分可以包含任意C代码。 您可以使用它来声明一些用C编写的辅助函数。 要将这些帮助程序导出到Python,请将它们的签名放在 cdef() 中。 (您可以在"C source"部分中使用 static C关键字,如 static int myhelper(int x) { return x * 42; } 因为这些辅助只是在同一个C文件中生成的"魔术"C代码中引用。)

这可以用于例如将"crazy"宏包装到更标准的C函数中。 额外的C语言层在其他方面也很有用,喜欢调用期望一些复杂的参数结构的函数,你喜欢用C而不是Python构建。 (另一方面,如果您只需要调用"类似函数"的宏,那么您可以直接在 cdef() 中声明它们,就好像它们是函数一样。)

生成的C语言代码应该在运行它的平台(或Python版本)上独立相同,因此在简单的情况下,您可以直接分发预生成的C语言代码并将其视为常规C扩展模块(这取决于CPython上的 _cffi_backend 模块。) 上面示例 中的特殊Setuptools行是针对更复杂的情况,我们需要重新生成C源代码————例如: 因为重新生成此文件的Python脚本本身会查看系统以了解它应包含的内容。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3