我一直在尝试获取一个由十六进制(unicode latin-1)值组成的imgdata字符串,该字符串通过指向imgdata的指针从Python传递给我编写的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值
值应为:
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
最佳答案
巨蟒并不是你想要的那么难。这看起来有点像:
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
编辑:阅读投票支持的评论(不相关,因为他删除了它们)。他解释了如何用你的方法纠正错误。
哦,好吧,他坚持,这是他的密码:
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个字符指针组成的数组是不正确的,向它传递指针是双重错误的,并且它没有在ArgumentError
中消亡的唯一原因是c_void_p
中的argtypes
接受了很多而没有抱怨——Python整数和字符串,以及ctypes指针和数组。