[C++-sig] Re: Manipulating arguments with CallPolicies::precall?

Arve Knudsen aknuds-1 at broadpark.no
Tue Feb 3 20:12:08 CET 2004


Hi, thanks for taking time. I'll try to explain what it is I'm trying to 
achieve, maybe I'm going at it the completely wrong way.

Thing is I need to work with an existing Python persistence framework 
written in C, where you're supposed to derive from a certain PyTypeObject. 
There isn't currently any way to inherit directly from a Python class 
defined outside of boost::python is there? I've tried registering the 
inheritance from within Python itself, but Python complains about 
incompatible instance layouts (or something).

As a workaround I've tried creating a thin wrapper C++ class_, where I 
fill in the Python interface (.def) by looping over the PyTypeObject's 
(the one I want to inherit from) method definitions. By doing this I 
implicitly expose the PyTypeObject's methods without writing explicit 
wrapping methods, so my class can adapt to an eventual change in 
interface. I have some mock-up code that seems to work:
PyMethodDef *md(typ->tp_methods);
string mn;
while (md->ml_name) {
	if (static_cast<PyCFunction>(md->ml_meth)) {
		mn = md->ml_name;
             if (md->ml_flags == METH_NOARGS)
			cls.def(mn.c_str(), (PyObject *(*)(PyObject *)) md->ml_meth);
             else if (md->ml_flags == METH_O) {
			cls.def(mn.c_str(), (PyObject *(*)(PyObject *, PyObject *)) 
md->ml_meth);
             }

             ++md;
	}
}

Since the exposed raw C functions expect a certain type of object however, 
I have to either derive my C++ class from the expected C struct, or 
extract a suitable struct from my C++ wrapper object. Deriving from the C 
struct seems to work, but at least I can't call the designated destructor 
(tp_dealloc) on my own object. Thus I'd prefer to wrap the C struct 
through composition, but I would need a way to extract this from an 
instance of my class and pass this to the raw C functions. I figured I 
could do this with CallPolicies::precall, but it would be hackish at best.

Anyway, to sum up. I would like to inherit (in the Python sense) my class_ 
 from an existing Python class, one way or the other :_) I apologize if 
there's some obvious approach which has evaded me.

Thanks

Arve Knudsen.


On Mon, 02 Feb 2004 17:23:40 -0500, David Abrahams 
<dave at boost-consulting.com> wrote:

> Arve Knudsen <aknuds-1 at broadpark.no> writes:
>
>> Hi
>>
>> I want to wrap a native C Python object in a C++ object that takes
>> care of constructing and destructing it properly
>
> I don't understand.  Do you mean something akin to
> boost::python::list, or something entirely different?
>> (there isn't any way
>> to specify custom allocation/deallocation routines are
>> there?)
>
> I don't understand the question.  allocation/deallocation routines
> for what?
>> However, I would like to send this object directly to the
>> associated routines (its part of an existing Python extension).
>
> What associated routines.
>> I haven't found any direct support for this kind of thing within
>> boost::python, since everything seems strongly tied to the contained
>> type (my wrapping C++ class). But, I figured it might be possible to
>> manipulate the Python argument tuple within CallPolicies::precall?
>
> Sorry, I'm completely lost.  I suggest you show some code that
> demonstrates what you'd like to be able to do, but which isn't
> supported.
>
> I didn't try very hard to understand the rest of the message, because
> I didn't even get this far :(
>






More information about the Cplusplus-sig mailing list