我假设您以某种方式填写了B::someObj,或者访问可能是随机的指针会使您的代码崩溃。鉴于这种情况,您必须同时公开 A 和 B 以通过 B 访问 A。我测试了以下代码,它可以按预期编译和工作:
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
struct A
{
int intVal;
char charVal;
};
struct B
{
A* someObj;
};
static boost::shared_ptr<B> create_b() {
boost::shared_ptr<B> retval(new B);
retval->someObj = new A; //<< WARNING: leakage ahead
retval->someObj->intVal = 3;
retval->someObj->charVal = 'a';
return retval;
}
BOOST_PYTHON_MODULE(test)
{
using namespace boost::python;
class_<A, A* >("A")
.def_readonly("intVal", &A::intVal)
.def_readonly("charVal", &A::charVal)
;
class_<B, boost::shared_ptr<B> >("B")
.def("__init__", make_constructor(&create_b))
.def_readonly("someObj", &B::someObj)
;
}
我的个人提示:如果您可以访问B 的定义,请将访问指针从B 更改为A 以使用boost::shared_ptr<A>。 Boost.Python 可以优雅地处理这个问题并正确地引用计数。在这种情况下,您的代码将如下所示:
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
struct A
{
int intVal;
char charVal;
};
struct B
{
boost::shared_ptr<A> someObj;
};
static boost::shared_ptr<B> create_b() {
boost::shared_ptr<B> retval(new B);
retval->someObj.reset(new A); //< no more leaks
retval->someObj->intVal = 3;
retval->someObj->charVal = 'a';
return retval;
}
BOOST_PYTHON_MODULE(test)
{
using namespace boost::python;
class_<A, boost::shared_ptr<A> >("A")
.def_readonly("intVal", &A::intVal)
.def_readonly("charVal", &A::charVal)
;
class_<B, boost::shared_ptr<B> >("B")
.def("__init__", make_constructor(&create_b))
.def_readonly("someObj", &B::someObj)
;
}
在linux下,你可以这样编译和测试这个模块:
$ g++ -I/usr/include/python2.7 -shared -fpic test.cc -lboost_python -lpython2.7 -o test.so
运行 Python 并检查您的代码是否正常工作:
>>> import test
>>> b = test.B()
>>> b.someObj.intVal
3
>>> b.someObj.charVal
'a'