Hi all
I am facing an "interesting" problem. I have factory functions implemented in
C++ that create opaque pointers. Such pointers are tossed around in python and
finally freed in C++. The module is implemented using boost::python.
Platform gcc 4.6.3/debian/boost 1.46, but also tried on msvc8/win7/boost 1.43

The opaque pointer refers to an IplImage, a C struct defined by OpenCV image
processing library.

I'm attaching a complete test case, however, in short:

IplImage* CreateImage()
{
    IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    std::cout << "Created " << img << std::endl;
    return img;
}

void ReleaseImage(IplImage*& img)
{
    std::cout << "Release Image " << img << std::endl;
    ::cvReleaseImage(&img);
}

When I run:
img = CameraConnect_Fake_Python.CreateImage()
CameraConnect_Fake_Python.ReleaseImage(img)

here's the output:
Created 0x8e34970
Release Image 0x70
Segmentation fault

For some reason that I don't grasp the reference-to-pointer is not passed
around correctly.

Still more interesting, if I try:

struct OPAQUE  {int unused;};

OPAQUE* factory()
{
    return new OPAQUE();
}

void destroyer(OPAQUE*& x)
{
    delete (x);
    x = NULL;
}
img = CameraConnect_Fake_Python.FACTORY()
CameraConnect_Fake_Python.DESTROYER(img)

It runs correctly!
Hope someone can help...
-- 
            Giuseppe Corbelli
WASP Software Engineer, Copan Italia S.p.A
Phone: +390303666318  Fax: +390302659932
E-mail: giuseppe.corbe...@copanitalia.com
#include <boost/python.hpp>

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/core/types_c.h>
#include <opencv2/core/core_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <boost/python/return_value_policy.hpp>

namespace bpy = boost::python;

struct OPAQUE
{
    int unused;
};

OPAQUE* factory()
{
    return new OPAQUE();
}

void destroyer(OPAQUE*& x)
{
    delete (x);
    x = NULL;
}

BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(OPAQUE)
BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(IplImage)

IplImage* CreateImage()
{ 
    IplImage* img = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    std::cout << "Created " << img << std::endl;
    return img; 
}

void ReleaseImage(IplImage*& img)
{
    std::cout << "Release Image " << img << std::endl;
    ::cvReleaseImage(&img); 
}

void ReleaseImageNoref(IplImage* img)
{
    std::cout << "Release ImageNoref " << img << std::endl;
    ::cvReleaseImage(&img);
}

void esporta_Base()
{
    bpy::def("CreateImage", &CreateImage, bpy::return_value_policy<bpy::return_opaque_pointer>());
    bpy::def("ReleaseImage", &ReleaseImage);
    bpy::def("ReleaseImageNoref", &ReleaseImageNoref);

    bpy::def("FACTORY", &factory, bpy::return_value_policy<bpy::return_opaque_pointer>());
    bpy::def("DESTROYER", &destroyer);
}

BOOST_PYTHON_MODULE(CameraConnect_Fake_Python)
{
    esporta_Base();
}
#!/usr/bin/python
# *-* coding: utf-8 -*-

import CameraConnect_Fake_Python

#~ img = CameraConnect_Fake_Python.CreateImage()
#~ print "Before", img
#~ CameraConnect_Fake_Python.ReleaseImage(img)
#~ CameraConnect_Fake_Python.ReleaseImageNoref(img)

print "Factory"
x = CameraConnect_Fake_Python.FACTORY()
print x
print "Delete"
CameraConnect_Fake_Python.DESTROYER(x)
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to