在 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 引用

如何在 C# 中实现 const 正确性? [复制]

Oracle中实现布尔类型

在c++中实现,如何创建一个char的数组

将字符串从 std::string 转换为 const char * 时出现数据丢失问题

如何在 C 中实现多分支树结构