将字符串列表从python/ctypes传递给期望char **的C函数

24 投票
6 回答
14461 浏览
提问于 2025-04-16 02:51

我有一个C语言的函数,它需要一个以\0结尾的字符串列表作为输入:

void external_C( int length , const char ** string_list) { 
   // Inspect the content of string_list - but not modify it.
} 

我想从Python中(使用ctypes)调用这个函数,输入是一个Python字符串的列表:

def call_c( string_list ):
    lib.external_C( ?? )

call_c( ["String1" , "String2" , "The last string"])

有没有什么建议可以帮助我在Python这边构建这个数据结构?请注意,我保证这个C函数不会改变string_list中字符串的内容。

祝好

joakim

6 个回答

6

使用ctypes

创建过期列表(字符串)

expiries = ["1M", "2M", "3M", "6M","9M", "1Y", "2Y", "3Y","4Y", "5Y", "6Y", "7Y","8Y", "9Y", "10Y", "11Y","12Y", "15Y", "20Y", "25Y", "30Y"]

发送字符串数组的逻辑

通过循环将字符串数组转换为字节数组

 expiries_bytes = []
    for i in range(len(expiries)):
        expiries_bytes.append(bytes(expiries[i], 'utf-8'))

使用ctypes来初始化一个指针,指针的长度与数组相同

expiries_array = (ctypes.c_char_p * (len(expiries_bytes)+1))()

将字节数组赋值给指针

expiries_array[:-1] = expiries_bytes
7

非常感谢,这个方法真是太有效了。我还做了一个不同的变体,像这样:

def call_c( L ):
    arr = (ctypes.c_char_p * (len(L) + 1))()
    arr[:-1] = L
    arr[ len(L) ] = None
    lib.external_C( arr )

然后在C语言的函数里,我遍历了这个(char **)列表,直到找到一个NULL值。

26

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后在另一个地方使用这些数据。这个过程就像是从一个盒子里拿东西,然后把它放到另一个盒子里。

有些时候,我们会遇到一些问题,比如数据的格式不对,或者我们想要的数据没有被正确地获取到。这就像是你想要一个苹果,但你却拿到了一个橙子。

为了避免这些问题,我们可以使用一些工具和方法来确保我们获取到的数据是正确的。就像在购物时,我们会检查一下商品的标签,确保它是我们想要的。

总之,处理数据的时候要小心,确保每一步都做对了,这样才能得到我们想要的结果。

def call_c(L):
    arr = (ctypes.c_char_p * len(L))()
    arr[:] = L
    lib.external_C(len(L), arr)

撰写回答