0

我有一些 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 ;
4

1 回答 1

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 );

我已经尝试过但没有意识到我需要将类对象包装在句柄<>中。

于 2013-06-03T09:42:35.517 回答