Python中Sigg C++类型的数组分配

2024-04-27 02:39:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个Python脚本,该程序使用SWIG公开了它的C++ API。 SWIG暴露函数的接口如下所示:

void writePixelsRect(JoxColor* colors, int left, int top, int width, int height);

JoxColor是一个POD结构,如下所示:

^{pr2}$

我可以很容易地在Python中创建一个JoxColor,然后调用writePixelsRect,如下所示:

c = JoxApi.JoxColor()
c.r = r
c.g = g
c.b = b
c.a = a
JoxApi.writePixelsRect(c, x, y, 1, 1)

用1x1像素的矩形反复调用writePixelResect非常慢,所以我想从python创建一个JoxColor数组,这样我就可以同时编写更大的矩形。这对于SWIG类型是可能的吗?在

注意,我没有访问C++库的源代码,它暴露了JoxCuffe和WrrePrimeXelsRT,所以我不能为此添加一个帮助函数。我也不想在系统中引入新的C++代码,因为它会迫使我的Python脚本的用户在他们运行的任何平台上编译C++代码。我确实可以在python环境中访问ctypes,所以如果我能够将ctypes中创建的float数组类型转换为JoxColor*类型,那么我就可以使用它了。在


Tags: 函数代码程序脚本api类型数组ctypes
2条回答

除非有特殊的打印图,这个SWIG原型

void writePixelsRect(JoxColor* colors, int left, int top, int width, int height);

意味着colorsJoxColor类型的单个对象,而不是数组。事实上,你只使用一个对象进行调用(尽管速度很慢),这表明这是正确的。所以传递一个数组很可能只会从SWIG包装器代码中得到一个类型不匹配的错误。在

但老实说,这看起来像是一个写任意大矩形的函数。因此,如果你想画一个更大的矩形(一种颜色),只需通过一个更大的宽度和/或高度:

^{pr2}$

编辑: 我不知道你在写饮料包装,我以为是给你的。在这种情况下,您可以编写一个类型映射,将Python列表(或tuple,或任何您想要的)转换成JoxColor*。 SWIG文档展示了一个如何将Python字符串列表转换为char**:http://www.swig.org/Doc1.3/Python.html#Python_nn59 typemap使用pythoncapi进行转换,您可以使用Python文档所说的任何内容。实际上,您分配了一个JoxColor数组,然后迭代Python列表对象并使用PyList_GetItem来获取每个单独的对象。这将返回SWIG包装的PyObject,您可以使用SWIG_ConvertPtr(list_item_py_object, (void**)&joxcolor_ptr, $descriptor(JoxColor *), 0)将其转换为指向实际JoxColor元素的指针。然后你可以把它复制到你的数组中。在

请记住,JoxColor*的类型映射将应用于JoxColor*出现的任何地方,您可以说JoxColor* colors将其专门化为仅此情况。在

仅供参考,默认情况下,SWIG将JoxColor*、JoxColor&;、JoxColor和JoxColor[]包装为单个对象的方式完全相同。Python只有对象,它不知道指针/引用/数组(Python列表也是对象)。http://www.swig.org/Doc1.3/Python.html#Python_nn22

这有点棘手,但至少在这部分代码中,您可以使用纯ctypes解决方案吗?基本上,由writepict导出的writepict文件名是手动导出的。C++命名为“Mangle”,因此,如果它可能只是^ {CD1}},如果库作者选择使它^ ^ },它可能是一些很复杂的东西,比如^ {CD3}}(这就是它是如何在我在系统上创建的虚构C++库中导出的)。在

在Linux上,此命令应该告诉您符号名称:

nm libjox.so | grep writePixel | cut -d " " -f 3

然后,保存该字符串并将其插入Python代码,如下所示:

^{pr2}$

假设_Z15writePixelsRectP8JoxColoriiii是函数在共享库中可访问的符号。运行这段代码只是在我的系统上使用了这样一个虚拟库:

#include <stdio.h>

struct JoxColor {
    float r, g, b, a;
};

void writePixelsRect(JoxColor *colors, int left, int top, int width, int height) {
    int p = 0;
    printf("size: %i, %i\n", width, height);
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            JoxColor color = colors[p];
            printf("pixel: %f, %f, %f, %f\n", color.r, color.g, color.b, color.a);
        }
    }
}

所以我希望它离在您的环境中工作的代码不会太远。在

相关问题 更多 >