Python - 使用ctypes传递指向C中函数的imgdata指针

时间:2014-02-01 07:02:45

标签: python c pointers pixel ctypes

我一直在尝试从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

1 个答案:

答案 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指针和数组。