Boost logo

Boost :

From: David Abrahams (abrahams_at_[hidden])
Date: 2000-12-07 15:03:21


----- Original Message -----
From: "Ullrich Koethe" <koethe_at_[hidden]>

> I strongly agree that this is a very important extension. Here is an
> example that might be a little easier to explain:
>
> Given two modules:
>
> - uimodule.so: contains wrapped C++ user interface widgets
> including, say, "Window"
> - logicmodule.so: contains application logic and a new widget
> "ResultsWindow"
> derived from "Window"
>
> Now the problem is: how can we use "ResultsWindow" like any window
> defined in the UI module, *without* merging the two modules into one?

This addresses what Prabhu is doing, but I think it leaves the OP (Ralf) out
in the cold. He's not interested in cross-module derivation AFAICT. He wants
the from_python/to_python functionality from one module to be available in
another, so that module A can use module B's wrapped types as parameters and
return values.

> I think it can already be done with BPL. (At least, the following worked
> in my tests.)
>
> 1. wrap the UI classes into uimodule.cpp as usual.
>
> 2. in uimodule.cpp: define functions to retrieve the class object for
> any class needed in another module:
>
> boost::python::detail::extension_class<Window> * get_window_class()
> {
> return
> dynamic_cast<boost::python::detail::extension_class<Window> *>
> (boost::python::detail::class_registry<Window>::class_object());
> }

Why do you need the downcast here?

> Declare these functions in a header "uicommon.hpp"
>
> 3. Wrap the application logic and "ResultWindow" into logicmodule.cpp
> as usual:
>
> boost::python::class_builder<ResultWindow>
> reswindow_class(logicmodule, "ResultWindow");
>
> 4. in logicmodule.cpp:
> - Include "uicommon.hpp"
> - declare the wrapped "Window" as base of the wrapped
> "ResultWindow"
>
> reswindow_class.get_extension_class()->
> declare_base(get_window_class());

I think I see a way to do this without the get_window_class() function. I
think it also will substantially cut down on code bloat. The usage would be
something like:

reswindow_class.declare_base(PyObject_Getattr(PyImport_GetModule("uimodule")
, "Window)))

We could provide some nice wrapper functions to insulate users from the
direct Python API stuff above. Hint: class_registry doesn't really need to
be templated.

> 5. *Dynamically* link logicmodule.so against uimodule.so
>
> g++ -shared -o logicmodule.so logicmodule.o uimodule.so \
> -lboostpython
>
> 6. Then in Python
>
> >>> import ui
> >>> import logic
> >>> result_window = logic.ResultWindow()
> >>> ui.show(result_window)
>
> Function show() from module ui can be applied to an object from module
> logic!
>
> [Note: to make this work, line 33 in module_builder.cpp must be
> commented out:
> // assert(name_holder.get() == 0);
> ]

Why? Have you got the latest module_builder.cpp with the destructor
~module_builder?

> David, is there anything inherently wrong with this? It certainly works
> in a simple test setting.

Mostly it looks terriffic, though I'd like to see it substantially
simplified.

-Dave


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