在 Python 中实现 char const *const names[] 的最佳方法是啥
Posted
技术标签:
【中文标题】在 Python 中实现 char const *const names[] 的最佳方法是啥【英文标题】: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" ;
【问题讨论】:
【参考方案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*);有两种解决方法:
-
声明一个大小数组
声明一个指针(类型:
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)
【讨论】:
以上是关于在 Python 中实现 char const *const names[] 的最佳方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
为啥在向量类中实现 operator= 时返回 const 引用