【问题标题】:What is the best way to implement char const *const names[] in Python在 Python 中实现 char const *const names[] 的最佳方法是什么
【发布时间】:2018-08-21 19:23:51
【问题描述】:

我需要将“char const *const names[]”参数传递给 C API。如何在 python ctypes 中获取指向常量 char 的常量指针?

我尝试使用 string1 = "你好第一" 名称 = ctypes.c_wchar_p(string1)

来自 C 的 Api 调用将是: char const *const names[] = { "AVeryLongName", "Name" };

【问题讨论】:

    标签: python ctypes


    【解决方案1】:

    您应该首先查看[Python 3.Docs]: ctypes - A foreign function library for Python。几个想法:

    • 您不能通过 CTypes 指定 constness(或者至少,我不知道如何)。关于Win的一个小例子:

      >>> from ctypes import wintypes
      >>> wintypes.LPCSTR == wintypes.LPSTR
      True
      

      因此,您的数组的 CTypes 包装器与 char *names[] = ....

      的包装器相同
    • Python 3开始,(8位)char序列(ctypes.c_char_p)是no不再是 str 对象,而是 [Python 3.Docs]: Built-in Types - Bytes Objects。它具有大部分常规字符串功能,但是当你声明一个文字时,你必须在它前面加上一个 b:

      >>> s = "Some string"
      >>> type(s)
      <class 'str'>
      >>> b = b"Some string"
      >>> type(b)
      <class 'bytes'>
      

      注意:要将常规字符串转换为字节,请使用[Python 3.Docs]: Built-in Types - str.encode(encoding="utf-8", errors="strict")"Dummy string".encode()

    • 无法从 Python 中完成一个未调整大小的数组 (char*);有两种解决方法:

      1. 声明一个大小数组
      2. 声明一个指针(类型:ctypes.POINTER(ctypes.c_char_p)


      让我们看一个 #1. 的简短示例:

      >>> ARRAY_DIM = 2
      >>> CharPArr = ctypes.c_char_p * ARRAY_DIM
      >>> CharPArr
      <class '__main__.c_char_p_Array_2'>
      >>> names = CharPArr(b"AVeryLongName", "Name".encode())
      >>> names, names[0], names[1]
      (<__main__.c_char_p_Array_2 object at 0x000002E6DC22A3C8>, b'AVeryLongName', b'Name')
      

      names 对象(上图)OK 可以传递给接受char const *const names[] 的函数,尽管我不确定该函数将如何确定long 是数组(除非另一个参数保持它的长度)。

      更新#0

      Python 2 也是如此:

      >>> ARRAY_DIM = 2
      >>> CharPArr = ctypes.c_char_p * ARRAY_DIM
      >>> CharPArr
      <class '__main__.c_char_p_Array_2'>
      >>> names = CharPArr("AVeryLongName", "Name")
      >>> names, names[0], names[1]
      (<__main__.c_char_p_Array_2 object at 0x7f39bc03c5f0>, 'AVeryLongName', 'Name')
      

    【讨论】:

    • 感谢您的回复。我将尝试使用 Python 3。
    • 不客气:) 让我知道它是如何工作的。我没有看到任何 Python 版本,所以我认为它是 3。对于 Python 2,它更简单,因为您可以忽略第二个项目符号。
    • CristiFati,实际上一开始我在尝试使用 Python 2。但是一旦我想通了,我会更新我的解决方案。
    • 我不明白。什么解决方案?这不行吗?那么最后你使用的是 Python 2 还是 *3?
    • 我正在使用 Python 2 并且解决方案已经更新,非常感谢指向 ctypes 指针的指针:)
    【解决方案2】:

    这就是我最终实现的方式,它似乎适用于 Python 2.7。

    示例 C 文件:

    void sam_test(char const *const names[],int n)
    {
     int i;
       for (i = 0; i < n; i++) {
         printf ("%s \n", (names[i]));
       }
    }
    

    Python:

    import ctypes
    lib = ctypes.cdll['./test.so']
    sam = lib['sam_test']
    String = ctypes.c_char_p * 3
    ii = String("First", "Second", "Third")
    name = ctypes.cast(ii, ctypes.POINTER(ctypes.c_char_p))
    sam(name, 3)
    

    【讨论】:

      猜你喜欢
      • 2012-07-21
      • 1970-01-01
      • 2017-11-25
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 2010-10-27
      • 2013-03-07
      相关资源
      最近更新 更多