Ctypes的优缺点

7

我听说在Python和Windows中,Ctypes可能会导致崩溃(或停止错误)。我应该避免使用它们吗?我从哪里听到的?当时我尝试控制Windows的各个方面、自动化等。

我听说过swig,但我更经常看到Ctypes。这里有什么危险吗?如果有,我应该注意什么?

我搜索了ctype pro con python。


这里有很多好的答案,我需要考虑一下并可能对每个答案进行更多评论。难怪我喜欢这个网站。 - phreaki
4个回答

13

在健壮性方面,我仍然认为swig比ctypes稍微优越一些,因为可以让C编译器更彻底地检查你的代码;然而,由于@Mark已经提到的“argtypes”特性,这现在已经没什么意义了(虽然在早期的ctypes版本中它更重要)。但是毫无疑问,相对于swig(以及sip、boost python和其他“封装”方法)来说,ctypes的运行时开销要大得多:因此,我认为在调用发生在关键瓶颈之外时,ctypes是一个方便的方式来调用DLL中的几个函数,而不是在性能关键的情况下使大型C库可用于Python。

想要在运行时性能与ctypes的便利之间找到一个不错的平衡点,同时还能够添加使用Python子集语法但以近似于C代码速度运行的更多代码,也可以考虑使用Cython - 一种类似于Python的语言,可以编译成C,并专门用于编写Python可调用扩展和封装C库(包括可能仅作为静态库而不是DLL可用的库:ctypes不能让你玩弄那些;-)。


6

如果使用得当,ctypes模块是安全的。

有些库提供更低级别的访问权限,有些模块仅仅允许您自己给自己惹麻烦。因此,一些模块比其他模块更加危险。但这并不意味着您不应该使用它们!

你可能听过有人谈论这样的东西:

#Crash python interpreter
from ctypes import *
def crashme():
    c = c_char('x')
    p = pointer(c)
    i = 0
    while True:
            p[i] = 'x'
            i += 1

Python解释器崩溃与Python代码本身出现运行时错误是不同的。例如,使用默认递归限制的无限递归会导致运行时错误,但Python解释器仍将保持活动状态。

另一个很好的例子是sys模块。尽管它可能会导致Python解释器崩溃,但您不会停止使用sys模块。

import sys
sys.setrecursionlimit(2**30)
def f(x):
  f(x+1)

#This will cause no more resources left and then crash the python interpreter
f(1)

还有很多库可以提供更低级别的访问。例如,gc模块可以被操纵以访问部分构造的对象,访问其字段可能会导致崩溃。

参考和想法来自:Crashing Python


1
由于我通常会破坏很多东西,所以这是一个我不知道的ctypes的好概述。 - phreaki

4

ctypes确实可能会导致崩溃,如果您正在使用的C库本身已经会导致崩溃。

如果有什么问题的话,ctypes可以帮助减少崩溃,因为您可以使用ctypesargtypes属性强制执行运行时类型安全性,该属性适用于使用ctypes的C函数。

但是,如果您的C库已经是稳定的并且经过测试,则绝对没有理由不使用ctypes,如果它可以满足将C和Python结合在一起的需求。


当然,我可以用它来做的不是我的 C 代码。这可能会给我一个学习更多知识的理由。 - phreaki

2

请解释一下为什么。不是我怀疑你(而且我也有这本书),但了解你的原因会很有帮助。 - Ryan Ginstrom
我也是。我不太擅长黑客或逆向工程方面的东西。我想访问一些对Python不易看到的机器部件。 - phreaki
如果您学习黑客和逆向工程师需要了解的相同类型的知识,那么您也将学习如何将这些技术应用于“访问Python难以看到的计算机部件”。 - Jim Dennis
2
这本书作为ctypes库的深入教程,向您展示如何运行极低级别的代码。 - Kenneth Reitz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接