如何在64位环境中处理ctypes中的字符串数组(char **)?

时间:2011-02-23 19:23:31

标签: python arrays string 64-bit ctypes

我正在使用ctypes在Python中使用libgphoto2。以下代码在32位计算机上成功,但在64位计算机(Linux,Ubuntu)上出现Segmentation Fault失败:

import ctypes

gp = ctypes.CDLL('libgphoto2.so')
a = gp.gp_library_version(0)
x = ctypes.c_char_p.from_address(a)
x.value

libphoto2,ctypes和python都来自存储库,所以我认为问题出现在我的代码中;我需要以更一般的方式或类似的方式考虑指针。 gp_library_version()返回const char **,一个字符串常量数组。其他gp_*函数运行正常。

2 个答案:

答案 0 :(得分:2)

问题在于,默认情况下,ctypes假定所有函数都返回int,即32位。但是,在64位系统上,指针是64位,因此您从指针返回值中删除高32位,因此当您尝试取消引用该无效指针时,您会得到段错误。

您可以通过为其restype属性分配类型来更改函数的预期返回类型,如下所示:

gp = ctypes.CDLL('libgphoto2.so')
gp.gp_library_version.restype = ctypes.POINTER(ctypes.c_char_p)
a = gp.gp_library_version(0)
print a[0].value

答案 1 :(得分:0)

如果你没有注释关于ctypes中函数的任何内容,则假定它们返回32位整数。在32位进程中,这些整数和指针大多可以互换 - 对于64位构建则不然。

刚做

gp.gp_library_version.restype = ctypes.c_void_p
在这种情况下,你的电话应该足够了(你仍然需要 x = ctypes.c_char_p.from_address(a)行)。

检查API文档,你应该在使用它之后自己释放这个指针(在这种情况下可能是的)。