我正在尝试使用ctypes在python中创建一个char *数组,以传递给库以填充字符串。 我期待4个字符串的长度不超过7个字符。
我的py代码看起来像这样
testlib.py
from ctypes import * primesmile = CDLL("/primesmile/lib.so") getAllNodeNames = primesmile.getAllNodeNames getAllNodeNames.argtypes = [POINTER(c_char_p)] results = (c_char_p * 4)(addressof(create_string_buffer(7))) err = getAllNodeNames(results)
lib.cpp
void getAllNodeNames(char **array){ DSL_idArray nodes; //this object returns const char * when iterated over network.GetAllNodeIds(nodes); for(int i = 0; i < (nodes.NumItems()); i++){ strcpy(array[i],nodes[i]); } }
当我尝试运行此代码时,我不断收到分段错误。 我已经从C创建了一个完美的测试但是在Python中我必须正确设置指针数组或其他东西。 它似乎进入循环中的第二个节点,然后遇到问题,因为我已经看到将数据吐出到命令行。 任何见解都会非常感激。
以下代码有效:
test.py:
import ctypes lib = ctypes.CDLL("./libtest.so") string_buffers = [ctypes.create_string_buffer(8) for i in range(4)] pointers = (ctypes.c_char_p*4)(*map(ctypes.addressof, string_buffers)) lib.test(pointers) results = [s.value for s in string_buffers] print results
test.c(使用gcc test.c -o libtest.so -shared -fPIC
编译为libtest.so):
#include void test(char **strings) { strcpy(strings[0],"this"); strcpy(strings[1],"is"); strcpy(strings[2],"a"); strcpy(strings[3],"test!"); }
正如Aya所说,你应该确保终止零的空间。 但我认为你的主要问题是字符串缓冲区是垃圾收集或类似的东西,因为没有直接引用它。 或者在没有为它们存储引用时,在字符串缓冲区的创建过程中导致其他问题。 例如,这导致相同地址的四倍而不是不同的地址:
import ctypes pointers = [ctypes.addressof(ctypes.create_string_buffer(8)) for i in range(4)] print pointers
在这一行:
results = (c_char_p * 4)(addressof(create_string_buffer(7)))
您正在创建一个7字节的缓冲区,然后尝试使用它来保存4个字符指针(每个可能是4个字节),然后还将4个8字节字符串复制到它可能碰巧指向的随机地址中。 您需要为每个字符串分配一个缓冲区,并分配指针数组。 像这样的东西:
s = [] for i in range(4): s[i] = create_string_buffer(8) results = (c_char_p * 4)(s);
我不能(轻松)测试代码,但根据你所说的,我的猜测就是问题在于……
results = (c_char_p * 4)(addressof(create_string_buffer(7)))
根据create_string_buffer()
的Python文档…
init_or_size
必须是一个整数,它指定数组的大小,或者是一个用于初始化数组项的字符串。如果将字符串指定为第一个参数,则将缓冲区设置为大于字符串长度的一个项目,以便数组中的最后一个元素是NUL终止字符。 可以将整数作为第二个参数传递,如果不应使用字符串的长度,则允许指定数组的大小。
…这意味着它正在创建一个char[7]
,但strcpy()
将尝试复制字符串的NULL
终止符,因此如果你的最大“节点名称”长度为7个字符,则需要一个char[8]
保持NULL
,尽管你可能会使用memcpy(array[i], nodes[i], 7)
而不是strcpy()
。
无论哪种方式,使用create_string_buffer(8)
代替它可能是最安全的。
需要了解更多c/c++开发分享Python使用ctypes传递char *数组并填充结果,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享Python使用ctypes传递char *数组并填充结果相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979240.html