B
Bill
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;
}
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;
}