[C++-sig] Define class in 2 scopes without re-exposing

Jim Bosch talljimbo at gmail.com
Mon Apr 16 17:32:00 CEST 2012


On 04/16/2012 03:15 AM, John Reid wrote:
>
>
> On 15/04/12 03:23, Dave Abrahams wrote:
>>
>> You can't do this; don't even try. Each C++ class has to have a unique
>> Python identity. If you just want to refer to the same class by a
>> different name, you can of course:
>>
>> BOOST_PYTHON_MODULE( _sandbox )
>> {
>> namespace bp = ::boost::python;
>> object inner;
>> {
>> bp::scope scope = bp::class_< Outer1>( "Outer1" );
>> inner = bp::class_< Inner>( "Inner" );
>> }
>>
>> {
>> object outer2 = bp::class_< Outer2>( "Outer2" );
>> outer2.attr("Inner") = inner;
>> }
>> }
>>
>
> I didn't know you could do that and it is useful but it is not quite
> what I had in mind. I would rather not pass the inner object around all
> the parts of my code that might need it. Is it possible to get it out of
> the registry in the second block? I'm guessing it must be in there
> somewhere as I get exactly the same behaviour (plus the warning message)
> if I just register the class in both blocks.
>

You can get it from the registry (see below), but it requires relying on 
what I'd consider implementation details of the library.

If you can, I'd recommend just importing the module that contains outer1 
and doing the above trick with that:

bp::object mod1 = bp::import("module1");
bp::object outer2 = bp::class_< Outer2 >("Outer2");
outer2.attr("Inner") = mod1.attr("Outer1").attr("Inner");

If you do really want to use the registry, I think you want something 
like this:

bp::converter::registration const * reg =
     bp::converter::registry::query(bp::type_id<Inner>());
assert(reg); // 0 if you haven't wrapped Inner yet
bp::object inner(bp::handle<>(bp::borrowed(
     reinterpret_cast<PyObject*>(reg.get_class_object())
)));



Jim


More information about the Cplusplus-sig mailing list