我一直在尝试从Python通过指向imgdata的指针传递一个imgdata字符串的十六进制(unicode latin-1)值到我编写的C函数。 C函数将这些十六进制源值(蓝绿色红色和Alpha)转换为灰度,然后将转换后的imgdata返回到dst指针地址。
目前,C函数打印出的源值不正确,与imgdata中的十六进制值有很大不同。在将Python中的imgdata传递给我的C函数时,对于我做错了什么建议?我的ctypes数据类型错了吗?
c函数的输出: src值:120 src值:212 src值:201 src值:1 src值:0 src值:0 src值:0 src值:0 src值:0 src值:0 src值:0 src值:0
值应为: 4,8,20,0,1,7,12,0,6,7,14,0
Python代码:
#imgdata format is BGRA
imgdata = '\x04\x08\x14\x00\x01\x07\x0c\x00\x06\x07\x0e\x00'
testlib = ctypes.CDLL('path/to/my/lib/testlib.so')
source = (c_char_p * 12) (imgdata)
destination = (c_uint8 * 12)()
testlib.grey.argtypes = (ctypes.c_void_p, ctypes.c_void_p,ctypes.c_int)
src = pointer(source)
dst = pointer(destination)
testlib.grey(dst,src,3)
p = ctypes.string_at(dst,12)
byte_array = map(ord, p)
C代码:
#include <stdio.h>
#include <stdint.h>
void grey(uint8_t *dst, uint8_t *sc, int num_pixels) {
int k;
for (k=0; k<12; k++)
{
printf("src values: %d ", *sc++);
}
// additional BGRA to Greyscale conversion code not shown
答案 0 :(得分:2)
Python并不是你想要的那么难。这看起来有点像:
imgdata = '\x04\x08\x14\x00\x01\x07\x0c\x00\x06\x07\x0e\x00'
testlib = ctypes.CDLL('path/to/my/lib/testlib.so')
dest = (c_uint8 * 12)()
testlib.grey(dest, imgdata, 12)
byte_array = bytearray(dest) # if you really neeed it
修改:阅读已投票的eryksun评论(自删除以来无关紧要)。他解释了如何使用您的方法使其正确。
哦,他坚持说,所以这是他的代码:
imgdata = '\x04\x08\x14\x00\x01\x07\x0c\x00\x06\x07\x0e\x00'
testlib = ctypes.CDLL('path/to/my/lib/testlib.so')
dest = (ctypes.c_char * len(imgdata))()
testlib.grey.restype = None
testlib.grey.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
testlib.grey(dest, imgdata, len(dest))
byte_array = bytearray(dest) # or just use dest.raw which is a python str
和他的解释:
c_char_p
是一个char*
,一个由12个字符串指针组成的数组是不正确的,并且传递一个指向它的指针是双重不正确的,并且它唯一的原因就是它不会在{{{ 1}} ArgumentError
中的c_void_p
接受了很多而没有抱怨 - Python整数和字符串,以及ctypes指针和数组。