【问题标题】:Manipulate a shared pointer coming from SWIG in python extension在 python 扩展中操作来自 SWIG 的共享指针
【发布时间】:2014-05-29 07:33:33
【问题描述】:

我正在尝试从 python 3.4 扩展访问现有的 C++ 对象。所以我有来自 C++ 的带有 SWIG 绑定的对象。然后我正在尝试构建一个 C++ python 扩展,我想在其中访问该对象。

我使用 python 这样做的原因是因为创建对象的库是一个外部库。所以我使用 python 绑定来生成对象,现在我需要在 C++ 中访问该对象。

为了更清楚,我使用的对象是Magick::Image(来自 ImageMagick++),我正在尝试将此对象传递给 python 扩展,然后将图像转换为 numpy ndarray。

这里的难点,是我通过共享指针访问Magick::Image对象。

所以在 python 中我有这个:

img = get_my_magick_image()
print(img)

<Swig Object of type 'std::tr1::shared_ptr< Magick::Image > *' at 0x7f32f6ecdd80>

这是我编写的 C++ 扩展,它能够访问 Magick::Image 方法,但我只能访问 shard_ptr 方法...当我尝试访问 Magick::Image 方法时出现段错误。我在python中使用readimg(img)来调用它。

PyObject* readimg(PyObject* self, PyObject* args) {
    std::tr1::shared_ptr< Magick::Image > * img;

    if (!PyArg_ParseTuple(args, "O", &img)) {
         PyErr_SetString(PyExc_TypeError, "error with parameters");
         return 0;
    }

    std::cout << "img : " << img << std::endl;
    std::cout << "&img : " << &img << std::endl;
    std::cout << "typeid(img).name() : " << typeid(img).name() << std::endl;
    std::cout << "typeid((*img)).name() : " << typeid((*img)).name() << std::endl;
    std::cout << "img->use_count()" << img->use_count() << std::endl;
    std::cout << "img->unique()" << img->unique() << std::endl;
    std::cout << "img->get()" << img->get() << std::endl;
    std::cout << "(*img).use_count()" << (*img).use_count() << std::endl;
    std::cout << "(*img)" << (*img) << std::endl;

    Magick::Geometry size = (*img)->size(); // SEGFAULT HERE
    unsigned h = size.height();
    std::cout << h << std::endl;
}

以及相关的输出:

img : 0x7f32f6ecdd80
&img : 0x7fff280fbad8
typeid(img).name() : PNSt3tr110shared_ptrIN6Magick5ImageEEE
typeid((*img)).name() : NSt3tr110shared_ptrIN6Magick5ImageEEE
img->use_count() : 10296384
img->unique() : 0
img->get() : 0x2
(*img).use_count() : 10296384
(*img) : 0x2
Segmentation fault

知道为什么我无法访问Magick::Image 方法吗?

【问题讨论】:

    标签: python c++ imagemagick swig shared-ptr


    【解决方案1】:

    我不是专家,但看起来img 没有正确初始化。你在documentation看到以下内容了吗?:

    其他对象

    O(对象)[PyObject *] 将 Python 对象(无需任何转换)存储在 C 对象指针中。因此,C 程序接收到的实际对象是 通过了。对象的引用计数不会增加。指针 存储的不是 NULL。

    该函数存储 原始 C 指针,所以我认为它与共享指针不兼容。 如果你需要一个共享指针,那么我会提出这样的建议:

    Magick::Image* _img = NULL;
    if (!PyArg_ParseTuple(args, "O", &_img)) {
         PyErr_SetString(PyExc_TypeError, "error with parameters");
         return 0;
    }
    std::tr1::shared_ptr< Magick::Image > img(_img);
    

    【讨论】:

    • 谢谢,但问题是在 python 中,我只能访问 Magick::Image 的共享指针。我看到了文档并尝试了几个解析参数但没有成功。你认为我可以使用 O& 并进行某种转换吗?
    • 啊,我明白了,它返回 PyObject*。可能 O& 是这样。像这样:stackoverflow.com/questions/19282054/…
    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多