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