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: [email protected]
#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
[email protected]
http://mail.python.org/mailman/listinfo/cplusplus-sig