c++ - 来自 Python 的 SWIG C++ 类型的数组分配

标签 c++ python swig ctypes

我正在为一个使用 SWIG 公开其 C++ API 的程序编写 Python 脚本。 SWIG 公开函数具有如下接口(interface):

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

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

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

我可以轻松地在 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 像素矩形重复调用 writePixelsRect 非常慢,所以我想从 python 创建一个 JoxColor 数组,这样我就可以写更大的矩形了。这对于 SWIG 类型可能吗?

请注意,我无权访问公开 JoxColor 和 writePixelsRect 的 C++ 库的源代码,因此我无法为此添加帮助功能。我也不想在系统中引入新的 C++ 代码,因为它会迫使我的 python 脚本的用户在他们运行的任何平台上编译 C++ 代码。我确实可以在 python 环境中访问 c​​types,所以如果我能以某种方式将在 ctypes 中创建的 float 组类型转换为 SWIG 的 JoxColor* 类型,它将对我有用。

最佳答案

这有点棘手,但至少对于这部分代码,您可以使用纯 ctypes 解决方案吗?基本上是手动查看共享库文件导出的符号,以找到 writePixelsRect 函数导出的名称。 C++ 会进行名称修改,因此虽然它可能只是 writePixelsRect 如果库作者选择将它设为 extern "C",它可能会更困惑一些,例如 _Z15writePixelsRectP8JoxColoriii(这就是它在我刚刚在我的系统上创建的虚拟 C++ 库中导出的方式)。

在 Linux 上,这个命令应该告诉你符号名称:

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

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

from ctypes import *

LIBRARY_NAME = 'libjox.so'
c = cdll.LoadLibrary(LIBRARY_NAME)

WIDTH = 20
HEIGHT = 20

class JoxColor(Structure):
    _fields_ = [("r", c_float), ("g", c_float), ("b", c_float), ("a", c_float)]

ColorBlock = JoxColor * (WIDTH * HEIGHT)

data_array = ColorBlock()

color = JoxColor(0, 0, 1, 0)
for i in range(WIDTH * HEIGHT):
    data_array[i] = color

c._Z15writePixelsRectP8JoxColoriiii(data_array, 0, 0, WIDTH, HEIGHT)

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

#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);
        }
    }
}

因此,我希望它离您的环境中的工作代码不远。

关于c++ - 来自 Python 的 SWIG C++ 类型的数组分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5862902/

相关文章:

python - 带有 Python 的 Noaa API。下载了数据集,我将如何打开它们?

java - Swig,将c指针转换为float[]

c++ - c++中的调车场算法

python - Python OpenCV:ValueError:太多值无法解包

c++ - Boost 程序选项 : multiple options for the same value

python - Python3(anaconda)中的tkinter, "AttributeError: module ' tkinter'没有属性 'Tk'“

python - 带有 Python 绑定(bind)的 C lib,两者都想要渲染

c - 痛饮 ruby "TypeError: Expected argument 0 of type int *, but got Fixnum 0"

c++ - 在 Xcode 中编译 C++ 时出现很多错误

c++ - G++ 4.5.0 中的 std::forward_as_tuple