将列表从Python传递到C,列表值在处理后未更新

问题描述 投票:0回答:1

这是示例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; ++i) {
        img[i].r -= r_mean;
        img[i].g -= g_mean;
        img[i].b -= b_mean;
    }
}

和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)

我用gcc struct_example.c -fPIC -shared -o struct_example.so编译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

我期望得到的是至少像素发生了变化。我错过了什么吗,如果我想在调用C算法后更改列表值,该怎么办。预先感谢。

python ctypes
1个回答
0
投票

列出[Python 3.Docs]: ctypes - A foreign function library for Python

像素在。dll中已更改(或者至少应该更改-我的声明仅基于查看代码,因为我并未实际对其进行测试),但是代码:

    从列表中创建(
  • CTypes
)数组时,(内部)元素未复制已复制,使2个容器完全decoupled
    因此,数组是动态创建的,并传递给函数,函数修改了内部的像素,但更改未反映在初始列表上
  • code00.py

  • #!/usr/bin/env python3 import sys import ctypes as ct class Pixel(ct.Structure): _fields_ = [ ("r", ct.c_ubyte), ("g", ct.c_ubyte), ("b", ct.c_ubyte), ("a", ct.c_ubyte), ] def __str__(self): return "RGBa({0:d}, {1:d}, {2:d}, {3:d})".format(self.r, self.g, self.b, self.a) def print_pixel(seq, index, header=None): text = "Sequence {0:s} element {1:d}:\n {2:s} - {3:s}".format("({0:s})".format(header) if header else "", index, repr(seq[index]), str(seq[index])) print(text) def main(*argv): pixel_list = [Pixel(255, 255, 255, 0), Pixel(128, 128, 128, 0), Pixel(0, 128, 128, 0)] PixelArray = Pixel * len(pixel_list) pixel_array = PixelArray(*pixel_list) pixel_index = 0 print_pixel(pixel_list, pixel_index, "pixel_list") print_pixel(pixel_array, pixel_index, "pixel_array") pixel_array[pixel_index].r = pixel_array[pixel_index].g = pixel_array[pixel_index].b = 128 # Modify pixel(s) in the array print_pixel(pixel_list, pixel_index, "pixel_list") print_pixel(pixel_array, pixel_index, "pixel_array") #processed_pixel_list = [pixel for pixel in pixel_array] #print_pixel(processed_pixel_list, pixel_index, "processed_pixel_list") if __name__ == "__main__": print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) main(*sys.argv[1:]) print("\nDone.")

    输出:

    e:\Work\Dev\StackOverflow\q059485131>c:\Install\pc064\Python\Python\03.08.01\python.exe code00.py Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 23:11:46) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Sequence (pixel_list) element 0: <__main__.Pixel object at 0x00000150C9628140> - RGBa(255, 255, 255, 0) Sequence (pixel_array) element 0: <__main__.Pixel object at 0x00000150C9628540> - RGBa(255, 255, 255, 0) Sequence (pixel_list) element 0: <__main__.Pixel object at 0x00000150C9628140> - RGBa(255, 255, 255, 0) Sequence (pixel_array) element 0: <__main__.Pixel object at 0x00000150C9628540> - RGBa(128, 128, 128, 0) Done.
    如图所示,无需

    。dll

    就可以复制行为。要解决该问题,请执行以下任一操作:
      使用数组(一旦创建)
    • 处理完数组后,从中创建一个列表(但我看不到任何好处)
    © www.soinside.com 2019 - 2024. All rights reserved.