[C++-sig] Re: Re: How to use call?
Dave Hawkes
daveh at cadlink.com
Sat Jun 15 04:49:52 CEST 2002
"David Abrahams" <david.abrahams at rcn.com> wrote in message
news:09e401c213df$33ce2d60$6601a8c0 at boostconsulting.com...
> What comment about MSVC?
>
I'm sure I saw a comment in the source a while back, but I can't find it
now...
> > > > I know the intention here is to copy the lvalue
> > >
> > > Huh? Which lvalue?
> > >
> >
> > The lvalue_from_python code that seems to get invoked
>
> There is no intention to copy an lvalue unless the explicit template
> argument to call<> is a non-pointer, non-reference type.
>
OK
> > > MyClass* p = call<MyClass*>(callable, arg1, arg2, ...);
> > >
> >
> > Then I will get the "Attempt to return dangling internal reference"
> > exception because I need to take possesion of the returned object.
>
> Well, yeah. Who else is going to keep it alive?
>
Yes, I know, that's my problem.
> >
> > see above, the returned object needs to be 'owned'.
>
> OK, you need what I mentioned to Dominic in a previous message: a smart
> pointer type which holds a PyObject* and which "points to" its contained
> lvalue. Yeah, that's not implemented, but patches are welcome.
>
Well here's my 'quick fix'. It is not feature complete, but if your
interested in something along these lines I can complete it:
namespace boost { namespace python {
template<class T>
struct class_handle {
class_handle() : class_ptr(NULL) {}
class_handle(PyObject* p) : h(p) { init(p); }
class_handle(handle<> h) : h(h) { init(h.get()); }
T* operator->() const { return class_ptr; }
T* get() const { return class_ptr; }
private:
void init(PyObject* p)
{
class_ptr = reinterpret_cast<T*>(objects::find_instance_impl(p,
type_id<T>()));
if(!class_ptr) {
PyErr_SetString(
PyExc_ReferenceError
, const_cast<char*>("attempt to find a class pointer from a
non class object"));
throw_error_already_set();
}
}
handle<> h;
T* class_ptr;
};
namespace converter {
template<>
struct return_from_python<handle<> > {
typedef handle<> result_type;
handle<> operator()(PyObject* p) const { return handle<>(p); }
};
}
}}
After putting this in an appropriate header(?) we can do:
class_handle<MyClass> pClass(call<handle<> >(pPyClass));
std::string msg = pClass->func();
There's some small issues such as should the class throw an exception or
just provide a NULL pointer. Also should I use a more generic way of
converting from python, but then class_handle would valid for more than just
our own classes?
Dave Hawkes
More information about the Cplusplus-sig
mailing list