Hi, I'm having a bit of trouble when writing a python extension. I can't seem to figure out what I did wrong. I tried to make a minimal example, but it's still quite a bit of code. It would be very appreciated if anyone could tell me what I've done wrong.
First a short description of what I've done. The extension just wraps a string and the class in it will just hold the string data. A 'get' method is suppsed to just return the string value. There's a python part that will call C/C++ functions in the extension. I've tried using the same approach SWIG has, so the class in the extension doesn't really have any methods, it's all done in methods in the module. This is what it looks like when I try it out (also tried with different python version and compiler): % python Python 2.4.3 (#1, Aug 1 2006, 16:54:29) [GCC 3.4.6] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> from example import StringWrapper >>> s = StringWrapper("S") >>> s.get() Traceback (most recent call last): File "<stdin>", line 1, in ? File "example.py", line 7, in get def get(self): return _example.get(self._s) TypeError: argument 1 must be SillyString, not SillyString Now this is what confuses me: Why does it say that I have the wrong type when it's the same type as it suggests? setup.py file: ########### from distutils.core import setup, Extension module1 = Extension('_example', sources = ['_example.cc']) setup (name = 'example', ext_modules = [module1]) example.py file: ############ #!/usr/bin/env python import _example class StringWrapper(object): def __init__(self, value): self._s = _example.new_string(value) def get(self): return _example.get(self._s) and finally, the c/c++ file '_example.cc': (I need to use c++ compiler which means I couldn't use 'staticforward' and the 'cstring is used instead of 'string.h' ) ######################## #include "Python.h" #include <cstring> // forward declaration extern PyTypeObject SillyStringType; typedef struct { PyObject_HEAD char s[21]; } SillyStringObject; PyObject * new_string(PyTypeObject *type, PyObject *args) { char *value = 0; if (!PyArg_ParseTuple(args, "s", &value)) return NULL; SillyStringObject *self = PyObject_NEW(SillyStringObject, &SillyStringType); if (self != NULL) { strncpy(self->s, value, 20); } return (PyObject *)self; } PyObject * get(PyTypeObject *type, PyObject *args) { SillyStringObject *o; if (!PyArg_ParseTuple(args, "O!", SillyStringType, &o)) return NULL; return (PyObject *)PyString_FromString(o->s); } PyMethodDef SillyStringMethods[] = { {"get", (PyCFunction)get, METH_VARARGS, "" }, {"new_string", (PyCFunction)new_string, METH_VARARGS, "" }, {NULL, NULL, 0, NULL} /* Sentinel */ }; PyTypeObject SillyStringType = { PyObject_HEAD_INIT(NULL) 0, /* ob_size */ (char *)"SillyString", /* tp_name */ sizeof(SillyStringObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)0, /* tp_dealloc */ (printfunc)0, /* tp_print */ (getattrfunc)0, /* tp_getattr */ (setattrfunc)0, /* tp_setattr */ (cmpfunc)0, /* tp_compare */ (reprfunc)0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)0, /* tp_hash */ (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "SillyString class." /* tp_doc */ }; extern "C" { PyMODINIT_FUNC init_example(void) { PyObject* m; SillyStringType.tp_new = PyType_GenericNew; if (PyType_Ready(&SillyStringType) < 0) return; m = Py_InitModule3("_example", SillyStringMethods, "_example module."); Py_INCREF(&SillyStringType); PyModule_AddObject(m, "SillyStringObject", (PyObject *)&SillyStringType); } } -- http://mail.python.org/mailman/listinfo/python-list