【问题标题】:How to handle array of strings (char **) in ctypes in a 64-bit environment?如何在 64 位环境中处理 ctypes 中的字符串数组(char **)?
【发布时间】:2023-04-04 18:28:03
【问题描述】:

我在 Python 中使用 ctypes 来处理 libgphoto2。以下代码在 32 位机器上成功,但在 64 位机器(Linux、Ubuntu)上失败并出现分段错误:

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_* 函数工作正常。

【问题讨论】:

    标签: python arrays string 64-bit ctypes


    【解决方案1】:

    问题在于,默认情况下,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
    

    【讨论】:

    • print a[0] 在我的 Fedora 14 系统 (python-2.7-8.fc14.1.x86_64) 上就足够了。
    【解决方案2】:

    如果您不对 ctypes 中的函数进行任何注释,则假定它们返回 32 位整数。在 32 位进程中,这些整数和指针大多是可互换的——对于 64 位构建则不然。

    只是在做

    gp.gp_library_version.restype = ctypes.c_void_p
    

    在这种情况下,您的电话就足够了(您仍然需要 x = ctypes.c_char_p.from_address(a) 行)。

    查看 API 文档,了解您是否应该在使用该指针后自行释放它(在这种情况下可能是的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2011-04-24
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多