[C++-SIG] Python calling C++ issues
Adrian Eyre
a.eyre at optichrome.com
Wed Dec 1 14:12:05 CET 1999
> Unfortunately, as of this moment, we have not yet successfully run our
> simple spam program.
You give up too easily... :)
Assuming you haven't changed the source from the original post:
The problem lies in the differences between Python extension modules and
Python extension types. You have written an extension module, but are
returning the values as if it were a type.
Here's how to fix it:
1. The file c_spam.cpp is pointless, so get rid of it.
2. In ext_spam.cxx:
static PyObject*
ext_new_Spam(PyObject* self, PyObject* args)
{
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b))
return NULL;
Spam* spam = new_Spam(a, b);
return Py_BuildValue("O", spam);
}
'Spam' is a C++ object, not a python object, and you can't just cast it
to a PyObject* and expect it to work. One way to do this is to pass back
a pointer to the object as a long:
static PyObject*
ext_new_Spam(PyObject* self, PyObject* args)
{
int a, b;
if (!PyArg_ParseTuple(args, "ii", &a, &b))
return NULL;
Spam* spam = new Spam(a, b);
return Py_BuildValue("l", (long) spam); // Or return PyInt_FromLong((long)
spam);
}
The Python script now stores this as a Python integer object.
3. In all other functions in ext_spam.cxx:
e.g.
static PyObject*
ext_Spam_Display(PyObject* self, PyObject* args)
{
Spam* spam;
if (!PyArg_ParseTuple(args, "O", &spam))
return NULL;
Spam_Display(spam);
return Py_BuildValue("");
}
Use:
static PyObject*
ext_Spam_Display(PyObject* self, PyObject* args)
{
Spam* spam;
if (!PyArg_ParseTuple(args, "l", &spam))
return NULL;
Spam_Display(spam);
Py_INCREF(Py_None); // Use these lines when you don't
return Py_None; // want to return a value
}
That should just about fix it.
A couple of other things:
o If you don't already have Mark Lutz's book "Programming Python",
get yourself a copy, and have a look through the chapters on
embedding and extending Python.
o If you want a better response, try posting to the main Python
mailing list, not the C++ binding one. This list is more to
do with the procedures for automating the process of creating
Python objects which mirror C++ objects.
o There are ways to do this sort of thing in a much more groovy way.
Judging by the test script:
#!/usr/bin/python
import c_spam
myspam=c_spam.new_Spam(8, 5)
c_spam.Spam_Display(myspam)
c_spam.delete_Spam(myspam)
print "python end"
...you are using it like a module, not a type. There are ways to get
Python to make your Spam object usable like this:
import c_spam
myspam = c_spam.Spam(8, 5)
myspam.Display()
del myspam
I don't really want to give too much away, then you'll never learn
how to do things yourself, but if you need any more assistance, don't
hesistate to mail back.
Good luck.
--------------------------------------------
Adrian Eyre <mailto:a.eyre at optichrome.com>
Optichrome Computer Solutions Ltd
Maybury Road, Woking, Surrey, GU21 5HX, UK
Tel: +44 1483 740 233 Fax: +44 1483 760 644
http://www.optichrome.com
--------------------------------------------
More information about the Cplusplus-sig
mailing list