How to create an instance of a python class from C++
Barry Scott
barry at barrys-emacs.org
Tue Mar 11 17:37:34 EDT 2014
On 5 Mar 2014, at 00:14, Bill <galaxyblue63 at 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
>
More information about the Python-list
mailing list