1

I am trying to access to an existing C++ object from a python 3.4 extension. So I have the object coming from C++ with a SWIG binding. Then I am trying to build a C++ python extension where I would like to access to that object.

The reason I do that with python is because the library who create the object is an external library. So I use the python binding to generate objects and now I need to access to that object in C++.

To be more clear the object I use is Magick::Image (from ImageMagick++) and I am trying to pass this object to a python extension and then convert the image to a numpy ndarray.

The difficulty here, it's I access to Magick::Image object by a shared pointer.

So in python I have this:

img = get_my_magick_image()
print(img)

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

Here is the C++ extension I wrote to be able to access to Magick::Image methods but I can only access to shard_ptr methods... I got a segfault when I try to access to Magick::Image methods. I use readimg(img) in python to call it.

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

And the related output :

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

Any idea why I can't access to Magick::Image methods ?

1 Answer 1

1

I'm not an expert but it looks like img is not properly initialized. Did you see the following in documentation?:

Other objects

O (object) [PyObject *] Store a Python object (without any conversion) in a C object pointer. The C program thus receives the actual object that was passed. The object’s reference count is not increased. The pointer stored is not NULL.

The function stores raw C pointer so I suppose it's not compatible with shared pointers. If you need a shared pointer, then I would propose something like this:

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you but the thing is in python I only have access to a shared pointer of Magick::Image. I saw the doc and tried several parse argumments without success. Do you think I could use O& and make a kind of conversion ?
Ah I see, it returns PyObject*. Probably O& is the way. Something like this: stackoverflow.com/questions/19282054/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.