使用 C 模块扩展 python
Posted
技术标签:
【中文标题】使用 C 模块扩展 python【英文标题】:Extending python with C module 【发布时间】:2011-03-31 19:52:44 【问题描述】:所以我有一个与 i2c 设备接口的 C 程序。我需要从 python 连接到该设备。我只是想知道是否值得将程序移植到 python 模块中,或者移植所涉及的工作量是否不会超过仅使用子进程执行程序。我知道我确信每个应用程序都不同,但我想知道是否值得我花时间学习 python C 扩展和移植这个程序。
更新:我可以完全访问 C 和 python 的源代码。但是在 python 方面已经完成了大量的工作,如果这很重要,我想尽可能减少对它的更改。而且我还想尽量减少必须对 C 进行的更改。这是可行的,但我没有编写它,它涉及到很多我不想重做的地址。
【问题讨论】:
【参考方案1】:我编写的第一个 Python 程序是一个从 C 库中调用函数的脚本,这听起来与您正在做的很接近。我使用了 ctypes,它的简单程度给我留下了深刻的印象:我只需编写几行 python 就可以从 python 访问每个库函数(根本不需要 C!)。我之前尝试过 Python C API,它需要更多样板。我没有尝试过 SWIG 或 Cython。
【讨论】:
【参考方案2】:我会推荐使用共享库的 ctypes。但是,不要依赖 C API 中的结构等复杂类型,这将是一个好主意。使用伪 OOP 方法最容易映射到 Python。
例如
foo_t* foo_new(void);
int foo_bar(foo_t*, int);
int foo_baz(foo_t*, int);
void foo_free(foo_t*);
在这里,您可以使用 ctypes 原生的东西。例如。 c_void_p 用于您的对象句柄和 c_int。 create_string_buffer(或类似的东西)也支持 c 样式字符串。
【讨论】:
【参考方案3】:我在使用 ctypes 时很幸运。但是,无论您选择什么,这次您可能不会获得任何时间,但下一次您的努力将比在 C 中完成整个事情要快得多。
【讨论】:
【参考方案4】:不要使用 Python C API,还有更简单的替代方案,最著名的是 cython。
cython 是一种类似 Python 的语言,它编译成 Python c 库的 C 代码。基本上它是具有 Python 语法和特性的 C 语言(例如 nice for 循环、异常等)。 cython 显然是为 python 编写 C 扩展的最值得推荐的方式。
您可能还想看看 ctypes,这是一个动态加载 C 库并从中调用函数的模块。如果您的 i2c 代码可用作共享库,则您可以完全不用本机绑定,从而简化开发和分发。
【讨论】:
【参考方案5】:您可以通过多种方式进行操作——Python C API,这似乎是您正在考虑的一种方式,还有SWIG、Cython、ctypes...只要您现有的 C代码可以做成一个库(带有可“从外部”调用的函数),你有很多选择。就个人而言,我推荐Cython
——它看起来越来越像 Python 的一个广泛子集,扩展得刚好足以允许有效地编译成机器代码并直接调用 C 库中的函数。
【讨论】:
+1 表示 Cython,但我认为 Cython 是 Python 的超集。 您是否有使用预先存在的 C 代码实现 Cython 的示例的链接?我发现似乎正在编写适合 python 的 C 代码 @carl,既然 Cython 没有 Python 的所有特性,它怎么可能是超集呢? “扩展子集”(实际上描述了任何两种语言之间的关系,如果按字面理解的话;-) 至少在数学上是正确的;-)。 @Falmarri,例如,请参阅groups.google.com/group/cython-users/browse_thread/thread/…,以获得更系统的处理ldots.org/pyrex-guide(使用 pyrex,cython 的前身,但是 - 除了提到限制 nof pyrex 已经消失cython;-) - 应该仍然适用)。如果需要封装 C++,请参阅wiki.cython.org/WrappingCPlusPlus。 @carl, "close but no cigar" 是一个很好的评估——Cython 的目标并不是成为 Python 的完整实现(尽管肯定远比Pyrex 曾经做过!-),Jython、IronPython、PyPy、Pynie 等的目标是(在我提到的四种情况中的三种情况下,实际上是——尽管不一定是最伟大的和最新的 Python 版本,可以肯定;-)。我可能错了,但我敢打赌 Cython 在接下来的任何时候都不会通过 Python 测试套件,哦,比如说,两年......任何接受者?-)以上是关于使用 C 模块扩展 python的主要内容,如果未能解决你的问题,请参考以下文章