Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #67763 > unrolled thread

How to create an instance of a python class from C++

Started byBill <galaxyblue63@gmail.com>
First post2014-03-04 16:14 -0800
Last post2014-03-12 18:10 +0100
Articles 9 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  How to create an instance of a python class from C++ Bill <galaxyblue63@gmail.com> - 2014-03-04 16:14 -0800
    Re: How to create an instance of a python class from C++ Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-04 18:55 -0700
      Re: How to create an instance of a python class from C++ Bill <galaxyblue63@gmail.com> - 2014-03-05 05:42 -0800
      Re: How to create an instance of a python class from C++ Grant Edwards <invalid@invalid.invalid> - 2014-03-05 16:08 +0000
        Re: How to create an instance of a python class from C++ Alister <alister.ware@ntlworld.com> - 2014-03-05 17:00 +0000
          Re: How to create an instance of a python class from C++ Grant Edwards <invalid@invalid.invalid> - 2014-03-05 17:14 +0000
            Re: How to create an instance of a python class from C++ Gene Heskett <gheskett@wdtv.com> - 2014-03-05 17:21 -0500
    Re: How to create an instance of a python class from C++ Barry Scott <barry@barrys-emacs.org> - 2014-03-11 21:37 +0000
    Re: How to create an instance of a python class from C++ Stefan Behnel <stefan_ml@behnel.de> - 2014-03-12 18:10 +0100

#67763 — How to create an instance of a python class from C++

FromBill <galaxyblue63@gmail.com>
Date2014-03-04 16:14 -0800
SubjectHow to create an instance of a python class from C++
Message-ID<0ab424e9-3a3f-4111-9f41-ff50ce73d70d@googlegroups.com>
Hello:

I can't figure out how to create an instance
of a python class from 'C++':

( I am relatively new to Python so excuse some of
  the following. )

In a .py file I create an ABC and then specialize it:

    from MyMod import *
    from abc import ABCMeta, abstractmethod

    # Declare an abstract base class.
    class Base(metaclass=ABCMeta):
        """Base class."""
        @abstractmethod
        def description(self):
            return "From the base class."

    # Declare a class that inerits from the base.
    class Derived(Base):
        """Derived class."""
        def description(self):
            return "From the Derived."

    # Register the derived class.
    RegisterClass(Derived)

Then from 'C++' (my implementation of RegisterClass)
I try to create an instance

    static PyObject *
    RegisterClass( PyObject *, PyObject *args ) {       // This gets called ok.

        PyObject *class_decl;
        if( ! PyArg_ParseTuple(args, "O", &class_decl) )
            return NULL;
        Py_INCREF(class_decl);

        PyTypeObject *typ = class_decl->ob_type;

        // Tried this.
        // PyObject *an = _PyObject_New(class_decl->ob_type); assert(an);
        // PyObject *desc = PyObject_CallMethod(an,"description",NULL); assert(desc);

        // Tried this.
        // PyObject *an = PyType_GenericNew((PyTypeObject *)class_decl->ob_type, NULL, NULL); assert(an);
        // assert(class_decl); assert(class_decl->ob_type); assert(class_decl->ob_type->tp_new);

        // This returns something.
        assert(class_decl); assert(class_decl->ob_type); assert(class_decl->ob_type->tp_new);
        PyObject *an_inst = class_decl->ob_type->tp_new(class_decl->ob_type,NULL, NULL); assert(an_inst);
        assert(class_decl->ob_type->tp_init);

        // This crashes.
        int ret = class_decl->ob_type->tp_init(an_inst,NULL, NULL); assert(ret == 0);
        // PyObject_CallMethod(an_inst,"__init__",NULL);
        // PyObject *an_inst = PyObject_CallMethod(class_decl,"__new__",NULL); assert(an_inst);

        // Never get here.
        PyObject *desc = PyObject_CallMethod(an_inst,"description",NULL); assert(desc);
        char *cp = _PyUnicode_AsString(desc);
        cerr << "Description:" << cp << endl;

        return PyLong_FromLong(0);
    }

    static PyMethodDef MyModMethods[] = {
        { "RegisterClass", RegisterClass, METH_VARARGS, "Register class." },
        {  NULL,           NULL,          0,             NULL             }
    };

    static struct PyModuleDef MyModMod = {
       PyModuleDef_HEAD_INIT,
       "MyMod",            // name of module
       NULL,                // module documentation, may be NULL
       -1,
       MyModMethods,
       NULL,
       NULL,
       NULL,
       NULL
    };

    PyMODINIT_FUNC
    PyInit_MyMod( void ) {
        PyObject* m = PyModule_Create(&MyModMod);
        if( m == NULL )
            return NULL;
            return m;
    }

    int
    main( int, char ** ) {

        PyImport_AppendInittab( "MyMod", PyInit_MyMod );

        Py_Initialize();

        const char *file_name = "z.py";
        FILE *fp = fopen(file_name,"r");
        if( fp ) {
            PyRun_SimpleFileExFlags(fp,file_name,1,0);
        }

        Py_Finalize();

        return 0;
    }

[toc] | [next] | [standalone]


#67775

FromIan Kelly <ian.g.kelly@gmail.com>
Date2014-03-04 18:55 -0700
Message-ID<mailman.7780.1393984546.18130.python-list@python.org>
In reply to#67763
On Tue, Mar 4, 2014 at 5:14 PM, Bill <galaxyblue63@gmail.com> wrote:
> Hello:
>
> I can't figure out how to create an instance
> of a python class from 'C++':
>
> ( I am relatively new to Python so excuse some of
>   the following. )
>
> In a .py file I create an ABC and then specialize it:

Why are you creating an ABC?  Most Python classes do not use them.
Maybe you have a reason for it, but it's irrelevant to what you're
currently trying to do.

> Then from 'C++' (my implementation of RegisterClass)
> I try to create an instance
>
>     static PyObject *
>     RegisterClass( PyObject *, PyObject *args ) {       // This gets called ok.
>
>         PyObject *class_decl;
>         if( ! PyArg_ParseTuple(args, "O", &class_decl) )
>             return NULL;
>         Py_INCREF(class_decl);

So far, so good.  The object that was passed in was the "Derived"
class object.  Since you presumably only want class objects to be
passed in, you might want to check that here using PyType_Check.

>         PyTypeObject *typ = class_decl->ob_type;

Okay, now if class_decl is the class object that was passed in, then
class_decl->ob_type is the *type* of that class object -- the
metaclass, which in this case would be ABCMeta.  You probably don't
need this, because you want to instantiate Derived, not ABCMeta.

>         // Tried this.
>         // PyObject *an = _PyObject_New(class_decl->ob_type); assert(an);
>         // PyObject *desc = PyObject_CallMethod(an,"description",NULL); assert(desc);

In Python, you instantiate a class by calling it.  You should do the
same in C, using PyObject_CallFunction.  But as above, note that you
want to call class_decl, not class_decl->ob_type.

PyObject_New doesn't do any initialization and is, I believe, meant to
be used when implementing types in C.

[toc] | [prev] | [next] | [standalone]


#67847

FromBill <galaxyblue63@gmail.com>
Date2014-03-05 05:42 -0800
Message-ID<0844f51e-151f-46ce-b0ea-456098d020e3@googlegroups.com>
In reply to#67775
> 
> So far, so good.  The object that was passed in was the "Derived"
> class object.  Since you presumably only want class objects to be
> passed in, you might want to check that here using PyType_Check.
>
    Yes. Will do.
> 
> >         PyTypeObject *typ = class_decl->ob_type;
> 
> In Python, you instantiate a class by calling it.  You should do the 
> same in C, using PyObject_CallFunction.  But as above, note that you
> want to call class_decl, not class_decl->ob_type.
> 

    Of course. That works.

Thanks.

Bill

[toc] | [prev] | [next] | [standalone]


#67855

FromGrant Edwards <invalid@invalid.invalid>
Date2014-03-05 16:08 +0000
Message-ID<lf7i50$2fv$2@reader1.panix.com>
In reply to#67775
On 2014-03-05, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Tue, Mar 4, 2014 at 5:14 PM, Bill <galaxyblue63@gmail.com> wrote:
>> Hello:
>>
>> I can't figure out how to create an instance
>> of a python class from 'C++':
>>
>> ( I am relatively new to Python so excuse some of the following. )
>>
>> In a .py file I create an ABC and then specialize it:
>
> Why are you creating an ABC?

Because it was the first binary computer that did calculations with
electronic switching elements (gates), and it would be really cool to
have one! The ABC also pioneered the use of capciators as regenerative
storage elements (it's how DRAM still works today).

http://en.wikipedia.org/wiki/Atanasoff%E2%80%93Berry_Computer

It predated ENIAC, and it's clear that some of the features of ENIAC
were inspired by the ABC after John Mauchly visited Iowa State and saw
the ABC.

-- 
Grant Edwards               grant.b.edwards        Yow! I can't decide which
                                  at               WRONG TURN to make first!!
                              gmail.com            I wonder if BOB GUCCIONE
                                                   has these problems!

[toc] | [prev] | [next] | [standalone]


#67857

FromAlister <alister.ware@ntlworld.com>
Date2014-03-05 17:00 +0000
Message-ID<DKIRu.5674$NZ3.5621@fx33.am4>
In reply to#67855
On Wed, 05 Mar 2014 16:08:00 +0000, Grant Edwards wrote:

> On 2014-03-05, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> On Tue, Mar 4, 2014 at 5:14 PM, Bill <galaxyblue63@gmail.com> wrote:
>>> Hello:
>>>
>>> I can't figure out how to create an instance of a python class from
>>> 'C++':
>>>
>>> ( I am relatively new to Python so excuse some of the following. )
>>>
>>> In a .py file I create an ABC and then specialize it:
>>
>> Why are you creating an ABC?
> 
> Because it was the first binary computer that did calculations with
> electronic switching elements (gates), and it would be really cool to
> have one! The ABC also pioneered the use of capciators as regenerative
> storage elements (it's how DRAM still works today).
> 
> http://en.wikipedia.org/wiki/Atanasoff%E2%80%93Berry_Computer
> 
> It predated ENIAC, and it's clear that some of the features of ENIAC
> were inspired by the ABC after John Mauchly visited Iowa State and saw
> the ABC.

But it was not programmable

the first programmable electronic computer was 'Colossus'
which was developed during WWII but remained classified by the UK govt 
for many years afterwards 

http://en.wikipedia.org/wiki/Colossus_computer





-- 
You are not dead yet.  But watch for further reports.

[toc] | [prev] | [next] | [standalone]


#67858

FromGrant Edwards <invalid@invalid.invalid>
Date2014-03-05 17:14 +0000
Message-ID<lf7m19$pk2$1@reader1.panix.com>
In reply to#67857
On 2014-03-05, Alister <alister.ware@ntlworld.com> wrote:
>>
>>> Why are you creating an ABC?
>> 
>> Because it was the first binary computer that did calculations with
>> electronic switching elements (gates), and it would be really cool to
>> have one! The ABC also pioneered the use of capciators as regenerative
>> storage elements (it's how DRAM still works today).
>> 
>> http://en.wikipedia.org/wiki/Atanasoff%E2%80%93Berry_Computer
>> 
>> It predated ENIAC, and it's clear that some of the features of ENIAC
>> were inspired by the ABC after John Mauchly visited Iowa State and saw
>> the ABC.
>
> But it was not programmable

True.  It had only one program that was hard-wired into it when it was
built as opposed to the external patch-cords and switches that were
used on machines like Colossus and ENIAC to alter the wiring.

> the first programmable electronic computer was 'Colossus' which was
> developed during WWII but remained classified by the UK govt for many
> years afterwards 
>
> http://en.wikipedia.org/wiki/Colossus_computer

-- 
Grant Edwards               grant.b.edwards        Yow! Hmmm ... A hash-singer
                                  at               and a cross-eyed guy were
                              gmail.com            SLEEPING on a deserted
                                                   island, when ...

[toc] | [prev] | [next] | [standalone]


#67890

FromGene Heskett <gheskett@wdtv.com>
Date2014-03-05 17:21 -0500
Message-ID<mailman.7844.1394058070.18130.python-list@python.org>
In reply to#67858
On Wednesday 05 March 2014 17:09:53 Grant Edwards did opine:

> On 2014-03-05, Alister <alister.ware@ntlworld.com> wrote:
> >>> Why are you creating an ABC?
> >> 
> >> Because it was the first binary computer that did calculations with
> >> electronic switching elements (gates), and it would be really cool to
> >> have one! The ABC also pioneered the use of capciators as
> >> regenerative storage elements (it's how DRAM still works today).
> >> 
> >> http://en.wikipedia.org/wiki/Atanasoff%E2%80%93Berry_Computer
> >> 
> >> It predated ENIAC, and it's clear that some of the features of ENIAC
> >> were inspired by the ABC after John Mauchly visited Iowa State and
> >> saw the ABC.
> > 
> > But it was not programmable
> 
> True.  It had only one program that was hard-wired into it when it was
> built as opposed to the external patch-cords and switches that were
> used on machines like Colossus and ENIAC to alter the wiring.
> 
> > the first programmable electronic computer was 'Colossus' which was
> > developed during WWII but remained classified by the UK govt for many
> > years afterwards
> > 
> > http://en.wikipedia.org/wiki/Colossus_computer

What machine was it that had about 12,000 12AU7 vacuum tubes in it for 
logic?  They had one of those, adapted to read the output of a bed of 
photocells installed in a Harris sheet fed press on the SUI campus in the 
later 1950's.  I saw it running once, grading the test score sheets from 
the Iowa Tests that were being used in lieu of the high price per seat S-B 
IQ test in the Iowa schools.  It was IIRC a somewhat difficult test when 
they threw it at me in the 7th grade a decade earlier, they claimed the 
test score were interchangeable with the S-B scores, but I somehow managed 
a 147 on it at the time.

Cheers, Gene
-- 
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
Genes Web page <http://geneslinuxbox.net:6309/gene>

NOTICE: Will pay 100 USD for an HP-4815A defective but
complete probe assembly.

[toc] | [prev] | [next] | [standalone]


#68249

FromBarry Scott <barry@barrys-emacs.org>
Date2014-03-11 21:37 +0000
Message-ID<mailman.8067.1394579420.18130.python-list@python.org>
In reply to#67763
On 5 Mar 2014, at 00:14, Bill <galaxyblue63@gmail.com> wrote:

> Hello:
> 
> I can't figure out how to create an instance
> of a python class from 'C++':
> 

Why not use pycxx from http://sourceforge.net/projects/cxx/?

This lib does all the heavy lifting for you for both python2 and python3.
Has docs and examples.

Barry
PyCXX maintainer.



> ( I am relatively new to Python so excuse some of
>  the following. )
> 
> In a .py file I create an ABC and then specialize it:
> 
>    from MyMod import *
>    from abc import ABCMeta, abstractmethod
> 
>    # Declare an abstract base class.
>    class Base(metaclass=ABCMeta):
>        """Base class."""
>        @abstractmethod
>        def description(self):
>            return "From the base class."
> 
>    # Declare a class that inerits from the base.
>    class Derived(Base):
>        """Derived class."""
>        def description(self):
>            return "From the Derived."
> 
>    # Register the derived class.
>    RegisterClass(Derived)
> 
> Then from 'C++' (my implementation of RegisterClass)
> I try to create an instance
> 
>    static PyObject *
>    RegisterClass( PyObject *, PyObject *args ) {       // This gets called ok.
> 
>        PyObject *class_decl;
>        if( ! PyArg_ParseTuple(args, "O", &class_decl) )
>            return NULL;
>        Py_INCREF(class_decl);
> 
>        PyTypeObject *typ = class_decl->ob_type;
> 
>        // Tried this.
>        // PyObject *an = _PyObject_New(class_decl->ob_type); assert(an);
>        // PyObject *desc = PyObject_CallMethod(an,"description",NULL); assert(desc);
> 
>        // Tried this.
>        // PyObject *an = PyType_GenericNew((PyTypeObject *)class_decl->ob_type, NULL, NULL); assert(an);
>        // assert(class_decl); assert(class_decl->ob_type); assert(class_decl->ob_type->tp_new);
> 
>        // This returns something.
>        assert(class_decl); assert(class_decl->ob_type); assert(class_decl->ob_type->tp_new);
>        PyObject *an_inst = class_decl->ob_type->tp_new(class_decl->ob_type,NULL, NULL); assert(an_inst);
>        assert(class_decl->ob_type->tp_init);
> 
>        // This crashes.
>        int ret = class_decl->ob_type->tp_init(an_inst,NULL, NULL); assert(ret == 0);
>        // PyObject_CallMethod(an_inst,"__init__",NULL);
>        // PyObject *an_inst = PyObject_CallMethod(class_decl,"__new__",NULL); assert(an_inst);
> 
>        // Never get here.
>        PyObject *desc = PyObject_CallMethod(an_inst,"description",NULL); assert(desc);
>        char *cp = _PyUnicode_AsString(desc);
>        cerr << "Description:" << cp << endl;
> 
>        return PyLong_FromLong(0);
>    }
> 
>    static PyMethodDef MyModMethods[] = {
>        { "RegisterClass", RegisterClass, METH_VARARGS, "Register class." },
>        {  NULL,           NULL,          0,             NULL             }
>    };
> 
>    static struct PyModuleDef MyModMod = {
>       PyModuleDef_HEAD_INIT,
>       "MyMod",            // name of module
>       NULL,                // module documentation, may be NULL
>       -1,
>       MyModMethods,
>       NULL,
>       NULL,
>       NULL,
>       NULL
>    };
> 
>    PyMODINIT_FUNC
>    PyInit_MyMod( void ) {
>        PyObject* m = PyModule_Create(&MyModMod);
>        if( m == NULL )
>            return NULL;
>            return m;
>    }
> 
>    int
>    main( int, char ** ) {
> 
>        PyImport_AppendInittab( "MyMod", PyInit_MyMod );
> 
>        Py_Initialize();
> 
>        const char *file_name = "z.py";
>        FILE *fp = fopen(file_name,"r");
>        if( fp ) {
>            PyRun_SimpleFileExFlags(fp,file_name,1,0);
>        }
> 
>        Py_Finalize();
> 
>        return 0;
>    }
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

[toc] | [prev] | [next] | [standalone]


#68288

FromStefan Behnel <stefan_ml@behnel.de>
Date2014-03-12 18:10 +0100
Message-ID<mailman.8096.1394644216.18130.python-list@python.org>
In reply to#67763
Barry Scott, 11.03.2014 22:37:
> On 5 Mar 2014, at 00:14, Bill wrote:
>> I can't figure out how to create an instance
>> of a python class from 'C++':
> 
> Why not use pycxx from http://sourceforge.net/projects/cxx/?
> 
> This lib does all the heavy lifting for you for both python2 and python3.
> Has docs and examples.

Yes, tool support definitely helps here. I was going to suggest Cython
(also for obvious reasons), where the code that the OP posted would look
like this:

  def RegisterClass(class_decl):
      an = type(class_decl)()
      print(an.description())
      return 0

Clearly substantially simpler than the posted C code (and certainly safer,
faster and more correct) - although that doesn't really help me much with
understanding what the intention of this code is, looks rather weird...

Stefan

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web