Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2001-04-22 10:58:27


----- Original Message -----
From: <rwgk_at_[hidden]>

> --- In boost_at_y..., Pearu Peterson <boost_at_c...> wrote:
> > The key question seems to be: How to declare a base class
> > that is defined in another module?:
> > symbol_class.declare_base(basic_class);
> Here are my questions:
>
> 1. Where is the source code that raises the "TypeError: derived"?

This (extension_class.cpp,140) looks like a likely candidate:

extension_instance* get_extension_instance(PyObject* p)
{
    // The object's type will just be some class_t<extension_instance>
object,
    // but if its meta-type is right, then it is an extension_instance.
    if (p->ob_type->ob_type != extension_meta_class())
    {
        PyErr_SetString(PyExc_TypeError, p->ob_type->tp_name);
------------------------^^^^^^^^^^^^^^^
        throw boost::python::argument_error();
    }
    return static_cast<extension_instance*>(p);
}

The best way to find out for sure is to set a conditional breakpoint in one
of Python's error-reporting functions.

> 2. I assume the TypeError is reported because something in the
> base.so does not know about the derived class. What is that
> something?

If you know the answer to 1., then you know the answer to 2.

Assuming it's the code quoted above, I would say that the problem is that
there are two instances of extension_meta_class() being generated because
the boost::python code (in files such as extension_class.cpp) is either
being compiled directly into each module, or a regular static library
(.lib/.a) is being generated and linked into each module. The solution would
be to build a dynamic library (.dll/.so) from all of the boost::python code
and link all modules to it dynamically. This would be a major improvement to
boost::python (especially for cross-module users), since currently all
modules duplicate the object code for the core functionality.

> 3. David, you mentioned dynamic linking. How exactly would
> I do this?

The answer depends on the platform. On Unix, usually it means linking to a
.so file just as you would with a .a file. On Windows, you usually link with
a .lib import library that is generated at the same time as a corresponding
.DLL. The point I was trying to make was that in order to make instances of
Derived, you need access to the code for its base classes. There are 2 ways
to get this code:

1. Compile it into the Derived module in addition to the Base module,
duplicating the code. In this case it seems to me, some things, like
dynamic_casting from a Base in the Base module to a Derived in the Derived
module, are unlikely to work.

2. Dynamically link the Derived module to the base module. If your
implmentation supports RTTI across dynamically-linked modules, it is more
likely to work.

Since you are only testing "without_downcast", you may not need that
functionality (for this test), but the issue of dynamically linking to the
Python library code is still there.

If you get that issue worked out, there's one more thing we should do: cause
the code for meta_class<extension_instance> and class_t<extension_instance>
to be instantiated in the shared library so that it isn't duplicated across
modules. I can help with that job.

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk