Python 将字符串作为c_字节数组传递给c

Python 将字符串作为c_字节数组传递给c,python,c,ctypes,Python,C,Ctypes,在C中,我有一个函数需要无符号字符数组s void writedata(unsigned char *datapos, int datanum) 我想从Python中传递一个标准字符串 writedata = parallel.writedata writedata.argtypes = [POINTER(c_ubyte), c_int] a = "test string" writedata(a, 11) 据我所知,字符串实际上是一个字节/字符数组,a是一个指针。但是

C
中,我有一个函数需要
无符号字符数组
s

void writedata(unsigned char *datapos, int datanum)
我想从Python中传递一个标准字符串

writedata = parallel.writedata
writedata.argtypes = [POINTER(c_ubyte), c_int]

a = "test string"
writedata(a, 11)

据我所知,字符串实际上是一个字节/字符数组,
a
是一个指针。但是,
ctypes
不同意:

ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected LP_c_ubyte instance instead of str
这很好,但我想为函数提供字节数组s和字符串s。这意味着这也应该起作用

ll = [0,1,2,3,4,5,6,7]
uints = (c_ubyte*8)(*ll)
writedata(uints, 8)
我很好奇为什么我不能同时做这两件事,因为就内存而言,我认为字节数组和字符串应该是相同的?也许这都是关于指针转换的

我还尝试将两个
ctypes
连接到同一个
C
函数,但这不起作用

解决方案:我重新制定了问题,并在这里得到了最佳答案:


如果我们转换字符串以匹配所需的参数类型,则可以使用相同的函数:

def writedata(值):
如果isinstance(值,str):
value=(ctypes.c_ubyte*len(value))(*bytearray(value))
writedaf(值,len(值))
为了验证我的理论,我创建了一个非常简单的库:

#包括
void writedata(无符号字符*datapos,int-datanum){
for(int index=0;index
我使用

clang-Wall-Werror-shared-fpic main.c-o libwritedata.so
我将共享库修改为
/usr/local/lib
,并创建了以下Python脚本:

导入ctypes
writedata=ctypes.CDLL('/usr/local/lib/libwritedata.so')。writedata
writedataf.argtypes=[ctypes.POINTER(ctypes.c_ubyte),ctypes.c_int]
def writedata(值):
如果isinstance(值,str):
value=(ctypes.c_ubyte*len(value))(*bytearray(value))
writedaf(值,len(值))
x=“短字符串”
写入数据(x)
uints=(ctypes.c_ubyte*len(x))(*bytearray(x))
写入数据(uints)
输出

短字符串
短线

我想你会发现这个问题很有用:@IkarusDeveloper它必须是
ctypes
。我已经编写了一个巨大的程序,所有其他的
Python
C
通信都是通过
ctypes
完成的。“据我所知,字符串实际上是一个字节/字符数组”——C字符串是,但不是Python字符串。Python字符串是Unicode代码点的抽象序列,可能有多个不同的内存表示形式。@user2357112supportsMonica公平参数。如果我知道只有ASCII字符,或者如果我把
b
放在前面,即
b“test string”
?@Pygmalion:a
b
放在前面会使它变成
bytes
,而不是
str
,所以它应该能工作。+1嗯,哦,它能工作,但我有时用实际的字符/字节数组访问同一个函数,也就是说,
uints=(c_ubyte*8)(*列表名称)
writedata(uints,8)
。我可以同时使用这两种数据类型吗?@Pygmalion我修改了脚本以处理这两种数据类型。我非常感谢您的努力,但这对我来说不起作用,因为我在C库中使用了不同的结构,它必须适用于所有函数。。。如果我加载同一个C库的多个实例,这个
struct
s将不可见。@Pygmalion我修改了脚本,使库只加载一次。
ll = [0,1,2,3,4,5,6,7]
uints = (c_ubyte*8)(*ll)
writedata(uints, 8)