I also added a constructor in my class B:
B( const WrappedClass* x )  :  m_wrapped_obj(*x) {}


From: Murali Donthireddy <donthireddy@yahoo.com>
To: Barry Scott <barry@barrys-emacs.org>
Cc: PyCXX and improvement <cxx-users@lists.sourceforge.net>
Sent: Thu, October 28, 2010 7:24:18 PM
Subject: Re: PyCXX and new style classes


Thanks for the reply.

BTW, I am using Python2 parts of version 2.6.1 of PyCXX.

I used simple.cxx as my starting point. But all of the methods in "new_style_class" return Py::None. How do I create and return an instance of new_style_class to the python code?  (In my application, I have more than one class, and a method of one class needs to return an instance of another class.)

With some help from someone who knows c++ better than me, I managed to do what I needed and it seems to work. But it felt like a herculean effort.

I added a second constructor to PythonClass and modified its self() to take an optional "owned" flag. I give all the code further down.

Let us call my subclasses of PythonClass A and B, they each wrap a pre-existing C++ class and hold a shared pointer to instances of those wrapped classes. Let us call the pointers a and b.

I am now able to return  a  PythonClassInstance of B from a method A as follows:
    const WrappedClass* x =  < something that returns an instance of WrappedClass>;
    return (new B(x))->self(true);

I must be being monumentally stupid because there is a vast gap between what I had to do and your comment "simple.cxx is all you need". I don't see how that can be the case when simple.cxx doesn't have a single method that returns anything, let alone instances of user defined classes.

Regardless of whether I did more than what was necessary, my extension works beautifully. I think PyCXX is a very nice tool. The fact that I could make changes to it is an indication of how well written it is. I am grateful for your work on PyCXX.


My changes to PythonClass, in header file CXX/Python2/ExtensionType.hxx:

    template<TEMPLATE_TYPENAME T> class PythonClass
    : public PythonExtensionBase
        static PythonClassInstance* alloc_empty() {
            PyObject *py_optlib_expr = extension_object_new(type_object(), Tuple().ptr(), Dict().ptr());
            return reinterpret_cast<PythonClassInstance*>(py_optlib_expr);

            : PythonExtensionBase()
            , m_class_instance( alloc_empty() )
            reinterpret_cast< Py::PythonClassInstance * >(selfPtr())->m_pycxx_object =
        static const T* obj_from_arg(Object arg) {
            PythonClassInstance * b = reinterpret_cast<PythonClassInstance *> (arg.ptr());
            const T *val = static_cast<T *>(b->m_pycxx_object);
            return val;
        virtual Object self(bool owned = false) // customization: Add optional argument owned.
            return Object( reinterpret_cast<PyObject *>( m_class_instance ), owned );


From: Barry Scott <barry@barrys-emacs.org>
To: Murali Donthireddy <donthireddy@yahoo.com>
Cc: PyCXX and improvement <cxx-users@lists.sourceforge.net>
Sent: Thu, October 28, 2010 4:59:03 PM
Subject: Re: PyCXX and new style classes

On 20 Oct 2010, at 19:14, Murali Donthireddy wrote:

Hi Barry,

I apologize for directly emailing you with a question. Completely understandable if you don't reply.

We have a user list that I'm CC'ing.

I am unable to figure out how to create, in C++ code, an instance of a new style class. The constructor requires a mysterious Py::PythonClassInstance* that I don't know how to generate.

You do not call the c'tor directly to create a instance.
You have to create instances using python methods.

The example simple.cxx seems to be the only source of info on about new style classes anywhere on the Internet, short of reading the implementation of PyCXX, but my C++ isn't good enough for that. 

Have you tried compiling and running simple? It shows the new style class stuff all working.

Any pointer or example code would be great.

simple.cxx is all you need. It shows you how to do most of the interesting stuff.

What exactly are you trying to do that simple.cxx does not do?