您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

通过ctypes从Python调用的C函数返回不正确的值

通过ctypes从Python调用的C函数返回不正确的值

清单[Python 3.Docs]:ctypes-Python的外部函数库。

为了在调用函数(驻留在.dll(.so)中)时正确转换所有内容(Python <=> C),需要指定2项内容(不包括x86调用约定(Win)):

参数类型 返回类型 在CTypes中,这可以通过指定:

argtypes-包含每个参数( CTypes)类型的列表(实际上是一个序列)(按它们在函数头中出现的顺序) restype -单ctypes的类型 旁注:上述方法的替代方法是对外部函数(CFUNCTYPE,WINFUNCTYPE,PYFUNCTYPE)进行原型设计-检查Function prototypes部分(在开头的URL中)。

无论如何:

无法指定 拼写错误(基本上与上一个项目符号相同) 它们中的任何(如果需要(1) ),将导致认被施加:所有被处理(C89风格)作为INT s,这(在大多数系统)是32位长。 这会生成未定义行为 (2)(在错误地指定它们时也适用),尤其是在64位 cpu / OS上,在后者中,较大类型的值(例如指针)可能会被截断。 显示错误可能很多,有时甚至会引起误解。

您拼写了argtype(末尾缺少s)。

纠正它,你应该没事

范例:

对于由libdll00.dll(libdll00.so)导出的具有以下标头的函数func00:

double func00(uint32_t ui, float f, long long vll[8], void *pv, char *pc);

在Python的等效是:

func00 = libdll00.func00
func00.argtypes = [ctypes.c_uint32, ctypes.c_float, ctypes.c_longlong * 8, ctypes.c_void_p, ctypes.POINTER(ctypes.c_char)]
'''
It would be a lot easier (nicer, and in most cases recommended)
  the last element to be ctypes.c_char_p,
  but I chose this form to illustrate pointers in general.
'''
func00.restype = ctypes.c_double

相同(或非常相似)场景(还有很多其他场景)的一些(更具破坏性的)结果:

[SO]:Python ctypes cdll.LoadLibrary,实例化一个对象,执行其方法,私有变量地址被截断(@CristiFati的回答) [SO]:不同操作系统上的python ctypes问题(@CristiFati的回答) 脚注 #1:从技术上讲,在某些情况下不需要指定它们。但是即使那样,最好还是指定它们,以消除任何可能的混淆:

没有参数的函数

  function_from_dll.argtypes = []

函数返回void:

  function_from_dll.restype = None

#2:顾名思义,未定义的行为( [Wikipedia]:未定义的行为)是无法“预测”(或保证)一段代码的结果的情况。主要情况:

按预期工作 不能按预期工作 有一些有趣的输出/副作用 崩溃

它的“美”在于有时似乎是完全随机的,有时它仅在某些特定情况(不同的机器,不同的OS,不同的环境……)下“复制” 。最重要的是,所有这些纯属巧合!问题出在代码(可能是当前代码(最高机率)或它使用的其他代码(库,编译器))上。

python 2022/1/1 18:34:47 有214人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶