在本文中,我们将详细介绍Python:SWIG与ctypes的各个方面,同时,我们也将为您带来关于day17Python区分函数和方法FunctionType、MethodType和type、Pyth
在本文中,我们将详细介绍Python:SWIG与ctypes的各个方面,同时,我们也将为您带来关于day17 Python 区分函数和方法 FunctionType 、MethodType 和 type、Python ctypes 用法集锦、Python Ctypes传递数据指针、Python ctypes参数错误的有用知识。
本文目录一览:- Python:SWIG与ctypes
- day17 Python 区分函数和方法 FunctionType 、MethodType 和 type
- Python ctypes 用法集锦
- Python Ctypes传递数据指针
- Python ctypes参数错误
Python:SWIG与ctypes
在python中,什么情况下SWIG比ctypes更好的选择是在共享库中调用入口点?假设您还没有SWIG接口文件。
两者的性能指标是什么?
答案1
小编典典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简单得多。
day17 Python 区分函数和方法 FunctionType 、MethodType 和 type
from types import FunctionType, MethodType
class Car(object):
def __init__(self):
pass
def run(self):
print("my car can run!")
@staticmethod
def fly(self):
print("my car can fly!")
@classmethod
def jumk(cls):
print("my car can jumk!")
c = Car()
# type(obj) 表示查看obj是由哪个类创建的.
# 实例方法
print(type(c.run)) # <class ''method''>
print(type(Car.run)) # <class ''function''>
# 静态方法
print(type(c.fly)) # <class ''function''>
print(type(Car.fly)) # <class ''function''>
# 类方法,因为类在内存中也是对象,所以调用类方法都是方法类型
print(type(c.jumk)) # <class ''method''>
print(type(Car.jumk)) # <class ''method''>
# 使用FunctionType, MethodType 来判断类型
# 实例方法
print(isinstance(c.run,MethodType)) # True
print(isinstance(Car.run,FunctionType)) # True
# 静态方法
print(isinstance(c.fly,FunctionType)) # True
print(isinstance(Car.fly,FunctionType)) # True
# 类方法
print(isinstance(c.jumk,MethodType)) # True
print(isinstance(Car.jumk,MethodType)) # True
"""结论
1. 类⽅法.不论任何情况,都是⽅法.
2. 静态方法,不论任何情况.都是函数
3. 实例方法,如果是实例访问.就是⽅法.如果是类名访问就是函数.
"""
Python ctypes 用法集锦
收集关于ctypes日常使用过程中的用法记录
list转换成ctypes里面的数组
In [1]: from ctypes import *
In [2]: ls = [1,2,3,4,5]
In [3]: array = (c_int*len(ls))(*ls)
In [4]: array
Out[4]: <__main__.c_long_Array_5 at 0x276ea18de48>
In [5]: for i in array: print(i)
1
2
3
4
5
学习链接:
ctypes中文记录
Python Ctypes传递数据指针
我正在访问API,但无法获取返回的数据。两个浮点指针将指向一个数据数组。我必须假设API正常运行。不同的函数调用提供了我要检索的数据的长度。length
尝试时,该值低于下面的值。
C函数头
int function(int,float * data1,float * data2)
ctypes设置
dll.function.argtypes = (c_int,POINTER(c_float),POINTER(c_float))
dll.function.restypes = c_int
尝试失败1:
x = c_float()
y = c_float()
status = dll.function(1,byref(x),byref(y))
程序崩溃或访问冲突写入。
尝试失败2:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1,x,y)
空指针错误
尝试失败3:
dll.function.argtypes = (c_int,c_void_p,c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1,y)
空指针错误
尝试失败4:
array = c_float * length
x = array()
y = array()
status = dll.function(1,byref(y))
程序崩溃
尝试5失败:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1,y)
空指针错误或ArgumentError:预期的LP_c_float实例,而不是LP_c_float_Array_ [length]
尝试失败6:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x,POINTER(c_float))
b = cast(y,POINTER(c_float))
status = dll.function(1,a,b)
程序崩溃
我想念什么,为什么?
我相信argtypes是正确的。我正在尝试适当地与他们会面,但是仍然存在问题。我是否需要以某种方式“分配”内存?(我确定获取数据后需要释放)。
这是在Windows 7上使用Python 2.7 32位的。
我已经浏览了其他类似问题,但没有找到解决方案。我想知道现在是否可以将此问题归咎于API。
Python ctypes参数错误
我用C
++编写了一个测试dll,以确保一切正常,然后再开始使用所需的更重要的dll。基本上需要两个双打并将其相加,然后返回结果。我一直在玩,并与其他测试功能一起工作,但由于错误我无法传递参数。我的代码是:
import ctypesimport stringnDLL = ctypes.WinDLL(''test.dll'')func = nDLL[''haloshg_add'']func.restype = ctypes.c_doublefunc.argtypes = (ctypes.c_double,ctypes.c_double)print(func(5.0,5.0))
它返回名为“ func”的行的错误:
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
我究竟做错了什么?谢谢。
答案1
小编典典您可能混淆了调用约定。我猜你有一个C函数声明这样的事情:
double haloshg_add(double d1, double s2){ return d1+d2;}
默认情况下,这将使用C调用约定。最简单的方法是在ctypes代码中更改调用约定:
nDLL = ctypes.CDLL(''test.dll'')
如果要将C代码中的调用约定更改为stdcall
(匹配ctypes.WinDLL
),则可以执行以下操作:
double __stdcall haloshg_add(double d1, double s2)
无论您做什么,都只需进行以下更改之一。如果您同时执行两个操作,则将导致反向失败!
如果是我,我只是将Python代码更改为使用C调用约定(use CDLL
)。这种变化影响最小。
关于Python:SWIG与ctypes的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于day17 Python 区分函数和方法 FunctionType 、MethodType 和 type、Python ctypes 用法集锦、Python Ctypes传递数据指针、Python ctypes参数错误的相关信息,请在本站寻找。
本文标签: