Python:SWIG与ctypes

问题描述 投票:53回答:10

在python中,在什么情况下SWIG比ctypes更适合在共享库中调用入口点?假设您还没有SWIG接口文件。 两者的性能指标是什么?

python c++ swig ctypes ffi
10个回答
63
投票

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等效设置简单得多。


0
投票

我发现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的平台。


89
投票

我有使用swig的丰富经验。 SWIG声称它是包装物品的快速解决方案。但在现实生活中......


Cons:

SWIG是针对每个人和20多种语言开发的。通常,它会导致缺点: - 需要配置(SWIG .i模板),有时候很棘手, - 缺少某些特殊情况的处理(进一步参见python属性), - 某些语言缺乏表现。

Python缺点:

1)代码风格不一致。 C ++和python具有非常不同的代码样式(当然很明显),使目标代码更加Python化的可能性非常有限。作为一个例子,从getter和setter创建属性是很重要的。见this q&a

2)缺乏广泛的社区。 SWIG有一些很好的文档。但如果有人发现了文档中没有的内容,则根本就没有信息。没有博客或谷歌搜索有帮助。因此,在这种情况下,必须大量挖掘SWIG生成的代码......这太糟糕了,我可以说......

Pros:

  • 在简单的情况下,它非常快速,简单和直接
  • 如果您生成一次swig接口文件,则可以将此C ++代码包装为其他20多种语言(!!!)。
  • 关于SWIG的一个重要问题是表现。从版本2.04开始,SWIG包含'-builtin'标志,这使得SWIG比其他自动包装方式更快。至少some benchmarks显示了这一点。

When to USE SWIG?

因此,当我使用swig时,我总结了两个案例:

2)如果需要为多种语言包装C ++代码。或者,如果可能有时间需要分发多种语言的代码。在这种情况下,使用SWIG是可靠的。

1)如果需要从一些C ++库中快速包装几个函数以供最终使用。


Live experience

更新: 我们使用SWIG转换了我们的库,这是一年半的时间。

首先,我们制作了一个python版本。有几次我们遇到SWIG的麻烦 - 这是真的。但是现在我们将库扩展为Java和.NET。所以我们有3种语言,1个SWIG。而且我可以说SWIG在节省大量时间方面发挥了作用。

更新2: 我们在这个库中使用SWIG已经两年了。 SWIG已集成到我们的构建系统中。最近我们对C ++库进行了重大的API更改。 SWIG工作得很好。我们唯一需要做的就是为.i文件添加几个%重命名,这样我们的CppCamelStyleFunctions()现在在python中的looks_more_pythonish。首先,我担心可能出现的一些问题,但没有出错。这是惊人的。只需几种编辑,一切都以3种语言分发。现在我相信在我们的案例中使用SWIG是一个很好的解决方案。

更新3: 我们在图书馆使用SWIG已有3年多了。主要变化:python部分完全用纯python重写。原因是Python现在用于我们库的大多数应用程序。即使纯python版本比C ++包装更慢,用户也可以更方便地使用纯python,而不是使用本机库。

SWIG仍用于.NET和Java版本。

这里的主要问题是“如果我们从一开始就启动项目,我们会使用SWIG进行python吗?”。我们会! SWIG允许我们快速将产品分发到多种语言。它工作了一段时间,使我们有机会更好地了解用户的要求。


13
投票

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


10
投票

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

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


8
投票

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


7
投票

我将成为逆势而且建议,如果可以的话,你应该使用standard Python API编写你的扩展库。从C和Python的角度来看,它确实很好地集成了......如果你有使用Perl API的经验,你会发现它是一个非常令人愉快的惊喜。

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

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


6
投票

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

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


5
投票

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

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

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


3
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.