boost.python避免两次注册内部类,但仍然在python中公开

时间:2013-06-03 08:45:58

标签: boost-python

我有一些C ++数据结构,其中模板化的外部结构具有内部结构。根据模板参数,内部结构可能是也可能不是同一类型。当我使用boost.python将结构暴露给python时,我希望能够将内部类称为Outer.Inner。在我的boost.python暴露代码中,我应该只暴露每个不同的内部类型一次。我可以查询boost.python注册表以避免多次暴露同一个内部类,但我该怎么做才能使以前暴露的内部类成为其外部类的属性?考虑到这个被剥离的例子,问题可能会更清楚:

#include <boost/python.hpp>

struct inner {
};

template< typename T >
struct outer {
    typedef inner inner_t;

    static const char * name();

    static
    void expose() {
        using namespace boost::python;

        class_< outer< T > > outer_class( name() );

        // check if inner type is in registry already
        const type_info inner_info = boost::python::type_id< inner_t >();
        const converter::registration * inner_registration
            = boost::python::converter::registry::query( inner_info );
        if( inner_registration == 0 || inner_registration->m_to_python == 0 ) {
            // not already in registry
            scope outer_scope( outer_class );
            class_< inner_t > inner_class( "Inner" );
        } else {
            // already in registry because exposed via different outer
            // what to put here? In python we need Outer.Inner to exist
        }
    }
};

template<>
const char *
outer< int >::name() { return "IntOuter"; }

template<>
const char *
outer< double >::name() { return "DoubleOuter"; }

BOOST_PYTHON_MODULE( inner_classes )
{
    outer< int >::expose();
    outer< double >::expose();
}

这是我想要运行的python代码:

import inner_classes as IC

IC.IntOuter.Inner
IC.DoubleOuter.Inner

为了完整性,这里有一个Jamroot来编译上面的内容:

import python ;
use-project boost : $(BOOST_ROOT) ;

project : requirements <library>/boost/python//boost_python ;

python-extension inner_classes : inner-classes.cpp ;

install install
  : inner_classes 
  : <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION 
    <location>. 
  ;

local rule run-test ( test-name : sources + )
{
    import testing ;
    testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
run-test test : inner_classes test_inner_classes.py ;

1 个答案:

答案 0 :(得分:0)

事实证明,一旦你知道boost.python的常见情况,这是非常简单的。在python这工作:

IC.DoubleOuter.Inner = IC.IntOuter.Inner

但不是我想要的解决方案。在C ++中,这有效:

scope outer_scope( outer_class );
outer_scope.attr( "Inner" ) = handle<>( inner_registration->m_class_object );

我已经尝试但没有意识到我需要将类对象包装在句柄&lt;&gt;中。