在蟒蛇,在什么情况下是痛饮一个更好的选择比ctypes用于调入境点的共享图书馆?让我们假设你已经没有痛饮口文件(s)。

什么是业绩指标的两个?

有帮助吗?

解决方案

SWIG生成(相当难看)C或C ++代码。它很容易用于简单的函数(可以直接翻译的东西),并且相当容易用于更复杂的函数(例如输出参数的函数需要额外的转换步骤以在Python中表示。)为了更强大的接口,你经常使用需要写入C的位作为接口文件的一部分。除了简单的使用之外,你需要了解CPython以及它如何表示对象 - 不是很难,但要记住一些事情。

ctypes允许您直接访问C函数,结构和其他数据,并加载任意共享库。您不需要为此编写任何C,但您需要了解C的工作原理。你可以说,它是SWIG的另一面:它不会生成代码,并且在运行时不需要编译器,但对于任何简单使用的东西,它确实需要你理解C数据类型,铸造,内存管理和对齐工作。您还需要手动或自动将C结构,联合和数组转换为等效的ctypes数据结构,包括正确的内存布局。

在纯执行中,SWIG可能比ctypes更快 - 因为围绕实际工作的管理是在编译时在C中完成的,而不是在运行时在Python中完成的。但是,除非你接口很多不同的C函数,但每次只有几次,所以开销不太可能真的很明显。

在开发时,ctypes的启动成本要低得多:你不必学习接口文件,你不必生成.c文件并编译它们,你不必检查和沉默警告。您可以轻松地跳入并开始使用单个C函数,然后将其扩展为更多。您可以直接在Python解释器中进行测试和尝试。包装大量代码有点单调乏味,尽管有人试图让它变得更简单(比如ctypes-configure。)

另一方面,SWIG可用于为多种语言生成包装器(除非需要填写特定于语言的详细信息,例如我上面提到的自定义C代码。)当包装SWIG可以提供大量代码时在没有多少帮助的情况下,代码生成也可以比ctypes等等设置起来更简单。

其他提示

我有丰富的经验使用口.痛饮权利要求,它是一种快速解决方案包裹的东西。但在现实生活中...


缺点:

口是发展成为一般情况下,对于每个人和用20多种语言。一般来说,它导致缺点:
-需要配置(痛饮.我的模板),有时候是棘手的,
-缺乏处理的一些特殊情况下(见python性质的进一步的),
-缺乏表现为一些语言。

蟒蛇缺点:

1) 代码式不一致.C++和python有非常不同的代码风格(也就是显而易见的,一定),则可能性的一个痛饮使目标代码的更多Pythonish是非常有限。作为一个例子,它是对心脏创造性,从干将和制定者。看看 这q&a

2) 缺乏广泛的社区.痛饮有一些很好的文件。但是,如果一个抓住的东西是不是在该文件,没有信息。没有博客,也不是谷歌上搜索有所帮助。因此,一个有严重挖口产生的代码,在这种情况下...这是可怕的,我可以说...

赞成:

  • 在简单的情况下,这是真的快速、简便和直线前进

  • 如果你产生的痛饮界面文件一次,你可以把这C++码的任何其他20多种语言(!!!).

  • 一个大的关注痛饮一个表现。由于版2.04痛饮包括'-内'的标志,这使得痛饮速度甚至超过其他自动化方面的包装。至少 一些基准 显示了这一点。


当使用口?

所以我得出的结论对于我自己的两个情况时的痛饮被很好的使用:

2)如果一个需要包C++码 对于几种语言.或者,如果潜在的有可能是一个时间当一个需要分发的代码,用于多种语言。使用口是可靠的,在这种情况。

1)如果一个需要 迅速 包裹 只是几个 能从一些C++库,为最终用途。


生活经验

更新 :
这是一年半过去了,因为我们没有转化我们的图书馆通过使用口.

第一,我们做了一个蟒蛇的版本。有几个时刻,当我们经历过麻烦口-这是真的。但现在我们扩大了我们的库Java和。网。因此,我们有3种语言的1痛饮.我可以说 痛饮岩石 在节省很多时间。

更新2:
它是两年,因为我们用痛饮用于这种库。痛饮被纳入我们建立系统。最近,我们不得不主要API变化C++图书馆。痛饮完美工作。我们唯一需要做的是增加几个%重新命名。我的文件,使我们的 CppCamelStyleFunctions() 现在 looks_more_pythonish 在蟒蛇。第一,我感到关切的一些问题,可能出现,但没有什么去了错误的。这是惊人的。只是几个编辑和一切分布在3种语言。现在我相信,这是一个很好的解决方案使用的痛饮在我们的情况。

3的更新:
这是3年以我们用痛饮用于我们的图书馆。 主要变化:蟒蛇的一部分是完全写在纯粹的蟒蛇。其原因是,蟒蛇,是用于大多数应用程序的我们的图书馆。即使纯python版工作慢于C++的包装,这是更便于用户使用纯蟒蛇,不挣扎与当地图书馆。

口仍在使用。净和爪哇的版本。

这里的主要问题"会我们用痛饮用于python如果我们开始的项目从一开始?".我们会!痛饮使我们能够迅速分发我们的产品走向多种语言。它的工作一段时间它让我们有机会更好地了解我们的用户要求。

CTypes非常酷,比SWIG容易得多,但它的缺点是编写得不好或恶意编写的python代码实际上会导致python进程崩溃。您还应该考虑提升 python。恕我直言,它实际上比swig更容易,同时让你更好地控制最终的python界面。如果你正在使用C ++,你也不会添加任何其他语言。

根据我的经验,ctypes确实有一个很大的缺点:当出现问题时(并且它总是适用于任何复杂的接口),这是一个很难调试。

问题在于你的堆栈的很大一部分被ctypes / ffi魔术所掩盖,并且没有简单的方法可以确定你是如何到达特定点的,以及为什么参数值就是它们的原因。

你也可以使用 Pyrex ,它可以充当高级Python代码和低级C代码之间的粘合剂。例如, lxml 是用Pyrex编写的。

我会反对并建议,如果可以的话,你应该使用标准Python API 。从C和Python的角度来看,它确实很好地集成了......如果您对Perl API有任何经验,您会发现它非常令人惊喜。

Ctypes也很好,但正如其他人所说,它不会做C ++。

你想要包装的图书馆有多大?代码库的变化速度有多快?还有其他维护问题吗?这些都可能会影响编写Python绑定的最佳方法的选择。

ctypes很棒,但不处理C ++类。我还发现ctypes比直接C绑定慢约10%,但这在很大程度上取决于你的调用。

如果您打算使用ctypes,请查看Pyglet和Pyopengl项目,这些项目包含大量ctype绑定示例。

只是想添加一些我还没有提到的注意事项。 [编辑:哎呀,没看到Mike Steder的回答]

如果你想尝试使用非Cpython实现(比如PyPy,IronPython或Jython),那么ctypes是唯一可行的方法。 PyPy不允许编写C扩展,因此排除了pyrex / cython和Boost.python。出于同样的原因,ctypes是唯一适用于IronPython的机制,并且(最终,一旦它们全部工作)jython。

正如其他人提到的那样,不需要编译。这意味着如果出现.dll或.so的新版本,您可以将其删除,并加载该新版本。只要没有任何接口改变,它就是替代品的下降。

要记住的是SWIG仅针对CPython实现。由于PyPy和IronPython实现也支持ctypes,因此可能需要使用ctypes编写模块以与更广泛的Python生态系统兼容。

我发现SWIG在它的方法(通常不仅仅是Python)中有点臃肿,并且难以实现而不必跨越编写Python代码的痛点,以明确的思维方式对SWIG友好,而不是编写干净编写良好的Python代码。恕我直言,将C绑定编写到C ++(如果使用C ++),然后使用ctypes连接到任何C层,这是一个更简单的过程。

如果您正在连接的库具有C接口作为库的一部分,则ctypes的另一个优点是您不必编译单独的python绑定库来访问第三方库。这在制定纯python解决方案时特别好,避免了跨平台编译问题(对于在不同平台上提供的那些第三方库)。必须将编译后的代码嵌入到希望以跨平台友好方式部署在PyPi之类的软件包中,这是一种痛苦;关于使用SWIG或底层显式C代码的Python包,我最烦人的一点是它们的跨平台通用性。因此,如果您正在使用跨平台可用的第三方库并围绕它们开发python解决方案,请考虑这一点。

作为一个真实的例子,考虑PyGTK。这(我相信)使用SWIG生成C代码以连接到GTK C调用。我在最短的时间里使用它只是为了找到一个真正的痛苦来设置和使用,如果你没有按照正确的顺序在设置和一般情况下做一些奇怪的奇怪错误。这是一次令人沮丧的经历,当我看到GTK在网络上提供的interace定义时,我意识到将这些接口的翻译器写入python ctypes接口是一个简单的练习。一个名为PyGGI的项目诞生了,在一天之内,我能够重写PyGTK,成为一个功能更强大,更有用的产品,与GTK C-object-oriented接口完全匹配。它不需要编译C代码,使其跨平台友好。 (我实际上是在连接到webkitgtk之后,这不是那么跨平台)。我也可以轻松地将PyGGI部署到任何支持GTK的平台。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top