Revision: 8399
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at September 18, 2008 11:18 by tkf
Initial Code
==> sonmodule.h <==
typedef struct {
PyObject_HEAD
PyObject *str;
int num;
} Son;
#define MAKE_SON_NEW(self, type, rt_error) \
(self) = (Son *)(type)->tp_alloc((type), 0); \
if ((self) == rt_error) { return rt_error; } \
\
(self)->str = PyString_FromString(""); \
if ((self)->str == rt_error) { \
Py_DECREF((self)); \
return rt_error; \
} \
\
(self)->num = 0
#ifdef __SON_MODULE
/* ---------- inclue form sonmodule.c ---------- */
static PyTypeObject SonType;
#else
/* ---------- inclue form othere module to use api ---------- */
/* store all api here */
void **Son_API;
/* set alias for easy call */
#define SonType (*(PyTypeObject *)Son_API[0])
#define Son_info (*(PyObject *(*) (Son *))Son_API[1])
static int _import_son(void)
{
PyObject *son = PyImport_ImportModule("son");
PyObject *c_api = NULL;
if (son == NULL){ return -1; }
/* load c api */
c_api = PyObject_GetAttrString(son, "_Son_API");
if (c_api == NULL) {Py_DECREF(son); return -1;}
if (PyCObject_Check(c_api)) {
Son_API = (void **)PyCObject_AsVoidPtr(c_api);
}
Py_DECREF(c_api);
Py_DECREF(son);
if (Son_API == NULL) return -1;
return 0;
}
#define import_son() \
{ \
if (_import_son() < 0) { \
PyErr_Print(); \
PyErr_SetString( PyExc_ImportError, \
"son failed to import"); \
return; \
} \
}
#endif
/* __SONMODULE */
==> sonmodule.c <==
#include <Python.h>
#include "structmember.h"
#define __SON_MODULE
#include "sonmodule.h"
#undef __SON_MODULE
static void
Son_dealloc(Son* self)
{
Py_XDECREF(self->str);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Son_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Son *self;
MAKE_SON_NEW(self, type, NULL);
return (PyObject *)self;
}
static int
Son_init(Son *self, PyObject *args, PyObject *kwds)
{
PyObject *str=NULL, *tmp;
static char *kwlist[] = {"str", "num", NULL};
if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Si", kwlist,
&str,
&self->num)){
return -1;
}
if (str) {
tmp = self->str;
Py_INCREF(str);
self->str = str;
Py_DECREF(tmp);
}
return 0;
}
static PyMemberDef Son_members[] = {
{"num", T_INT, offsetof(Son, num), 0, "Sone num"},
{NULL} /* Sentinel */
};
static PyObject *
Son_getstr(Son *self, void *closure)
{
Py_INCREF(self->str);
return self->str;
}
static int
Son_setstr(Son *self, PyObject *value, void *closure)
{
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete the str attribute");
return -1;
}
if (! PyString_Check(value)) {
PyErr_SetString(PyExc_TypeError,
"The str attribute value must be a string");
return -1;
}
Py_DECREF(self->str);
Py_INCREF(value);
self->str = value;
return 0;
}
static PyGetSetDef Son_getseters[] = {
{"str", (getter)Son_getstr, (setter)Son_setstr, "str", NULL},
{NULL} /* Sentinel */
};
static PyObject *
Son_info(Son *self)
{
PyObject *dic = PyDict_New();
if (dic == NULL) {
printf("creating dict failed\n");
return NULL;
}
Py_INCREF(self->str);
PyDict_SetItemString(dic, "str", self->str);
PyDict_SetItemString(dic, "num", PyLong_FromLong( self->num ));
return dic;
}
static PyMethodDef Son_methods[] = {
{"info", (PyCFunction)Son_info, METH_NOARGS, "return info dic"},
{NULL} /* Sentinel */
};
static PyTypeObject SonType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"son.Son", /*tp_name*/
sizeof(Son), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Son_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Son objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Son_methods, /* tp_methods */
Son_members, /* tp_members */
Son_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Son_init, /* tp_init */
0, /* tp_alloc */
Son_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};
/* ---------- insert object into api array ---------- */
void *Son_API[] = {
(void *) &SonType,
(void *) Son_info,
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initson(void)
{
PyObject *m, *d;
PyObject *c_api;
if (PyType_Ready(&SonType) < 0){ return; }
m = Py_InitModule3("son", module_methods,
"Son Class");
if (m == NULL){ goto err; }
Py_INCREF(&SonType);
PyModule_AddObject(m, "Son", (PyObject *)&SonType);
/* ----- set api to module ----- */
d = PyModule_GetDict(m);
if (!d){ goto err; }
c_api = PyCObject_FromVoidPtr((void *)Son_API, NULL);
if (c_api == NULL){ goto err; }
PyDict_SetItemString(d, "_Son_API", c_api);
Py_DECREF(c_api);
return;
err:
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
"cannot load son module.");
}
return;
}
==> fathermodule.c <==
#include <Python.h>
#include "structmember.h"
#include "sonmodule.h"
typedef struct {
PyObject_HEAD
Son *son;
} Father;
static void
Father_dealloc(Father* self)
{
Py_XDECREF(self->son);
self->ob_type->tp_free((PyObject*)self);
}
static PyObject *
Father_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
Father *self;
self = (Father *)type->tp_alloc(type, 0);
if (self == NULL) { return NULL; }
MAKE_SON_NEW(self->son, &SonType, NULL);
return (PyObject *)self;
}
static int
Father_init(Father *self, PyObject *args, PyObject *kwds)
{
return 0;
}
static PyMemberDef Father_members[] = {
{NULL} /* Sentinel */
};
static PyObject *
Father_getson(Father *self, void *closure)
{
Py_INCREF(self->son);
return (PyObject *)self->son;
}
static int
Father_setson(Father *self, PyObject *value, void *closure)
{
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete the son attribute");
return -1;
}
if (! PyObject_TypeCheck(value, &SonType)) {/* SonType is from Son_API! */
PyErr_SetString(PyExc_TypeError,
"The str attribute value must be a Son");
return -1;
}
Py_DECREF(self->son);
Py_INCREF(value);
self->son = (Son *)value;
return 0;
}
static PyGetSetDef Father_getseters[] = {
{"son", (getter)Father_getson, (setter)Father_setson, "son", NULL},
{NULL} /* Sentinel */
};
static PyObject *
Father_info(Father *self)
{
PyObject *dic = PyDict_New();
if (dic == NULL) {
printf("creating dict failed\n");
return NULL;
}
PyDict_SetItemString(dic, "son",
Son_info(self->son));/* Son_info is from Son_API! */
return dic;
}
static PyMethodDef Father_methods[] = {
{"info", (PyCFunction)Father_info, METH_NOARGS, "return info dic"},
{NULL} /* Sentinel */
};
static PyTypeObject FatherType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"father.Father", /*tp_name*/
sizeof(Father), /*tp_basicsize*/
0, /*tp_itemsize*/
(destructor)Father_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Father objects", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Father_methods, /* tp_methods */
Father_members, /* tp_members */
Father_getseters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)Father_init, /* tp_init */
0, /* tp_alloc */
Father_new, /* tp_new */
};
static PyMethodDef module_methods[] = {
{NULL} /* Sentinel */
};
#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC
initfather(void)
{
PyObject* m;
if (PyType_Ready(&FatherType) < 0){ return; }
m = Py_InitModule3("father", module_methods,
"Father Class");
if (m == NULL){ return; }
Py_INCREF(&FatherType);
PyModule_AddObject(m, "Father", (PyObject *)&FatherType);
import_son();
}
==> setup.py <==
# python setup.py build build_ext --inplace
import sys
import os
from distutils.core import setup, Extension
son_module = Extension(
'son',
define_macros = [],
include_dirs = [],
libraries = [],
library_dirs = [],
extra_compile_args = [],
sources = ['sonmodule.c'])
father_module = Extension(
'father',
define_macros = [],
include_dirs = [],
libraries = [],
library_dirs = [],
extra_compile_args = [],
sources = ['fathermodule.c'])
setup(
name = 'storage',
version = '1.0',
description = '',
ext_modules = [son_module, father_module] )
==> test.txt <==
>>> import son
>>> sn = son.Son()
>>> import father
>>> fr = father.Father()
>>> sn.num = 12
>>> sn.str = "son str"
>>> sn.info()
{'num': 12L, 'str': 'son str'}
>>> fr.son
<son.Son object at 0xb7cd5070>
>>> fr.son.info()
{'num': 0L, 'str': ''}
>>> fr.info()
{'son': {'num': 0L, 'str': ''}}
>>> fr.son = sn
>>> fr.info()
{'son': {'num': 12L, 'str': 'son str'}}
Initial URL
http://arataka.wordpress.com/2008/09/18/python%e3%81%aec%e6%8b%a1%e5%bc%b5%e3%81%a7api%e3%82%92%e5%85%ac%e9%96%8b%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/
Initial Description
Initial Title
C API for a python extension module
Initial Tags
python, c, api, extension
Initial Language
C