将列表从Python传递到C,处理后列表值未更新
下面是示例C代码:将列表从Python传递到C,处理后列表值未更新,python,ctypes,Python,Ctypes,下面是示例C代码: #include <stdint.h> struct Pixel { uint8_t r; uint8_t g; uint8_t b; uint8_t a; }; void normalize(struct Pixel *img, uint32_t num, uint8_t r_mean, uint8_t g_mean, uint8_t b_mean) { for (uint32_t i = 0; i < num;
#include <stdint.h>
struct Pixel {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
void normalize(struct Pixel *img, uint32_t num, uint8_t r_mean, uint8_t g_mean, uint8_t b_mean)
{
for (uint32_t i = 0; i < num; ++i) {
img[i].r -= r_mean;
img[i].g -= g_mean;
img[i].b -= b_mean;
}
}
我使用gcc struct_示例.C-fPIC-shared-o struct_示例编译了C代码。因此
,运行Python代码并得到以下结果,这不是我期望的结果:
original pixels: [<__main__.Pixel object at 0x7f66c17f8e18>, <__main__.Pixel object at 0x7f66c1486400>, <__main__.Pixel object at 0x7f66c1486620>]
255 255 255 0
128 128 128 0
0 128 128 0
normalized pixels: [<__main__.Pixel object at 0x7f66c17f8e18>, <__main__.Pixel object at 0x7f66c1486400>, <__main__.Pixel object at 0x7f66c1486620>]
255 255 255 0
128 128 128 0
0 128 128 0
原始像素:[,]
255 255 255 0
128 128 128 0
0 128 128 0
标准化像素:[,]
255 255 255 0
128 128 128 0
0 128 128 0
我希望得到的是像素至少改变了。如果我遗漏了什么,如果我想在调用C算法后更改列表值,该怎么办。提前感谢。正在登录
像素在.dll中被更改(或者至少它们应该被更改-我的声明仅基于查看代码,因为我没有实际测试它),但是Python代码中有一个逻辑错误:
import ctypes
class Pixel(ctypes.Structure):
_fields_ = [('r', ctypes.c_ubyte),
('g', ctypes.c_ubyte),
('b', ctypes.c_ubyte),
('a', ctypes.c_ubyte)]
pixels = [Pixel(255, 255, 255, 0), Pixel(128, 128, 128, 0), Pixel(0, 128, 128, 0)]
pixels_num = len(pixels)
mean = 100
print('original pixels:', pixels)
for pixel in pixels:
print(pixel.r, pixel.g, pixel.b, pixel.a)
obj = ctypes.CDLL('struct_example.so')
obj.normalize.argtypes = (ctypes.POINTER(Pixel), ctypes.c_uint, ctypes.c_ubyte, ctypes.c_ubyte, ctypes.c_ubyte)
array_type = Pixel * pixels_num
obj.normalize(array_type(*pixels), pixels_num, mean, mean, mean)
print('normalized pixels:', pixels)
for pixel in pixels:
print(pixel.r, pixel.g, pixel.b, pixel.a)
- 从列表中创建(CTypes)数组时,(内部)元素被复制而未被引用,使两个容器完全解耦
- 因此,数组是动态创建的,并传递给函数,函数修改了内部的像素,但更改没有反映在初始列表中
#/usr/bin/env蟒蛇3
导入系统
将ctypes导入为ct
类像素(ct结构):
_字段=[
(“r”,ct.c_ubyte),
(“g”,ct.c__byte),
(“b”,ct.c_ubyte),
(“a”,ct.c_ubyte),
]
定义(自我):
返回“RGBa({0:d},{1:d},{2:d},{3:d})”格式(self.r,self.g,self.b,self.a)
def打印像素(顺序、索引、标题=无):
text=“Sequence{0:s}元素{1:d}:\n{2:s}-{3:s}”.format(({0:s})”.format(header)if header else“”,index,repr(seq[index]),str seq[index]))
打印(文本)
def主(*argv):
像素列表=[像素(255,255,255,0),像素(128,128,128,0),像素(0,128,128,0)]
像素阵列=像素*透镜(像素列表)
像素数组=像素数组(*像素数组列表)
像素指数=0
打印像素(像素列表、像素索引、“像素列表”)
打印像素(像素阵列、像素索引、“像素阵列”)
pixel_数组[pixel_index]。r=pixel_数组[pixel_index]。g=pixel_数组[pixel_index]。b=128#修改数组中的像素
打印像素(像素列表、像素索引、“像素列表”)
打印像素(像素阵列、像素索引、“像素阵列”)
#已处理的像素列表=[像素阵列中像素对像素]
#打印像素(已处理像素列表、像素索引、“已处理像素列表”)
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main(*sys.argv[1:])
打印(“\n完成”)
输出:
e:\Work\Dev\StackOverflow\q059485131>c:\Install\pc064\Python\Python\03.08.01\Python.exe code00.py
win32上的Python 3.8.1(tags/v3.8.1:1b293b6,2019年12月18日,23:11:46)[MSC v.1916 64位(AMD64)]64位
序列(像素列表)元素0:
-RGBa(255、255、255、0)
序列(像素数组)元素0:
-RGBa(255、255、255、0)
序列(像素列表)元素0:
-RGBa(255、255、255、0)
序列(像素数组)元素0:
-RGBa(128、128、128、0)
完成。
如图所示,可以在没有.dll的情况下复制该行为。要解决此问题,请执行以下操作之一:
- 使用阵列(创建阵列后)
- 处理完数组后,从中创建一个列表(但我看不到任何好处)
import ctypes
class Pixel(ctypes.Structure):
_fields_ = [('r', ctypes.c_ubyte),
('g', ctypes.c_ubyte),
('b', ctypes.c_ubyte),
('a', ctypes.c_ubyte)]
pixels = [Pixel(255, 255, 255, 0), Pixel(128, 128, 128, 0), Pixel(0, 128, 128, 0)]
pixels_num = len(pixels)
mean = 100
print('original pixels:', pixels)
for pixel in pixels:
print(pixel.r, pixel.g, pixel.b, pixel.a)
obj = ctypes.CDLL('struct_example.so')
obj.normalize.argtypes = (ctypes.POINTER(Pixel), ctypes.c_uint, ctypes.c_ubyte, ctypes.c_ubyte, ctypes.c_ubyte)
array_type = Pixel * pixels_num
obj.normalize(array_type(*pixels), pixels_num, mean, mean, mean)
print('normalized pixels:', pixels)
for pixel in pixels:
print(pixel.r, pixel.g, pixel.b, pixel.a)
- 从列表中创建(CTypes)数组时,(内部)元素被复制而未被引用,使两个容器完全解耦
- 因此,数组是动态创建的,并传递给函数,函数修改了内部的像素,但更改没有反映在初始列表中
#/usr/bin/env蟒蛇3
导入系统
将ctypes导入为ct
类像素(ct结构):
_字段=[
(“r”,ct.c_ubyte),
(“g”,ct.c__byte),
(“b”,ct.c_ubyte),
(“a”,ct.c_ubyte),
]
定义(自我):
返回“RGBa({0:d},{1:d},{2:d},{3:d})”格式(self.r,self.g,self.b,self.a)
def打印像素(顺序、索引、标题=无):
text=“Sequence{0:s}元素{1:d}:\n{2:s}-{3:s}”.format(({0:s})”.format(header)if header else“”,index,repr(seq[index]),str seq[index]))
打印(文本)
def主(*argv):
像素列表=[像素(255,255,255,0),像素(128,128,128,0),像素(0,128,128,0)]
像素阵列=像素*透镜(像素列表)
像素数组=像素数组(*像素数组列表)
像素指数=0
打印像素(像素列表、像素索引、“像素列表”)
打印像素(像素阵列、像素索引、“像素阵列”)
pixel_数组[pixel_index]。r=pixel_数组[pixel_index]。g=pixel_数组[pixel_index]。b=128#修改数组中的像素
打印像素(像素列表、像素索引、“像素列表”)
打印像素(像素阵列、像素索引、“像素阵列”)
#已处理的像素列表=[像素阵列中像素对像素]
#打印像素(已处理像素列表、像素索引、“已处理像素列表”)
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main(*sys.argv[1:])
打印(“\n完成”)
输出:
e:\Work\Dev\StackOverflow\q059485131>c:\Install\pc064\Python\Python\03.08.01\Python.exe code00.py
win32上的Python 3.8.1(tags/v3.8.1:1b293b6,2019年12月18日,23:11:46)[MSC v.1916 64位(AMD64)]64位
序列(像素列表)元素0:
-RGBa(255、255、255、0)
序列(像素数组)元素0:
-RGBa(255、255、255、0)
序列(像素列表)元素0:
-RGBa