Created
August 10, 2017 13:17
-
-
Save alaingalvan/db63858c35ff156f4d9723b33a4e867f to your computer and use it in GitHub Desktop.
Python C++ bindings code sample from docs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 1999 Michael P. Reilly, All rights reserved. | |
* Written by Michael P. Reilly. | |
*/ | |
/* headers */ | |
#include <Python.h> | |
/* Module globals */ | |
static PyObject *counter_error = NULL; | |
/* Counter type */ | |
staticforward PyTypeObject Counter_Type; | |
/* Counter object */ | |
typedef struct { | |
PyObject_HEAD | |
long value; | |
} Counter; | |
#define Counter_Check(v) ((v)->ob_type == &Counter_Type) | |
#define Counter_value(v) (((Counter *)(v))->value) | |
/* helper functions */ | |
static int | |
object2int(obj, value) | |
PyObject *obj; | |
long *value; | |
{ PyObject *temp; | |
if (Counter_Check(obj)) | |
*value = Counter_value(obj); | |
else if (PyInt_Check(obj)) | |
*value = PyInt_AsLong(obj); | |
else { | |
temp = PyNumber_Int(obj); | |
if (temp == NULL) { | |
PyErr_SetString(PyExc_TypeError, "expecting number"); | |
return 0; | |
} | |
*value = PyInt_AsLong(temp); | |
Py_DECREF(temp); | |
} | |
return 1; | |
} | |
/* constructor */ | |
static PyObject * | |
Counter_NEW(initial_value) | |
long initial_value; | |
{ Counter *object; | |
object = PyObject_NEW(Counter, &Counter_Type); | |
if (object != NULL) | |
object->value = initial_value; | |
return (PyObject *)object; | |
} | |
static void | |
Counter_dealloc(self) | |
PyObject *self; | |
{ PyMem_DEL(self); | |
} | |
/* Numeric emulation routines */ | |
/* In this case, it is easier to write a coercion routines than to | |
* all the little add, subtract, multiply, etc. routines. | |
*/ | |
static PyObject * | |
Counter_Neg(self) | |
PyObject *self; | |
{ return Py_BuildValue("i", -Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Pos(self) | |
PyObject *self; | |
{ return Py_BuildValue("i", Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Abs(self) | |
PyObject *self; | |
{ register long value = Counter_value(self); | |
return Py_BuildValue("i", (value < 0 ? -value : value)); | |
} | |
static int | |
Counter_Nonzero(self) | |
PyObject *self; | |
{ return (Counter_value(self) != 0); | |
} | |
static PyObject * | |
Counter_Invert(self) | |
PyObject *self; | |
{ return PyInt_FromLong(~Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Int(self) | |
PyObject *self; | |
{ | |
return PyInt_FromLong(Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Long(self) | |
PyObject *self; | |
{ | |
return PyLong_FromLong(Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Float(self) | |
PyObject *self; | |
{ | |
return PyFloat_FromDouble((double)Counter_value(self)); | |
} | |
static PyObject * | |
Counter_Oct(self) | |
PyObject *self; | |
{ char buf[100]; | |
sprintf(buf, "0%o", Counter_value(self)); | |
return PyString_FromString(buf); | |
} | |
static PyObject * | |
Counter_Hex(self) | |
PyObject *self; | |
{ char buf[100]; | |
sprintf(buf, "0x%x", Counter_value(self)); | |
return PyString_FromString(buf); | |
} | |
/* Convert them to integers if counters. */ | |
static int | |
Counter_Coerce(v, w) | |
PyObject **v, **w; | |
{ long i; | |
*v = PyInt_FromLong(Counter_value(*v)); | |
if (object2int(*w, &i)) { | |
*w = PyInt_FromLong(i); | |
} else | |
Py_INCREF(*w); | |
return 0; | |
} | |
static PyNumberMethods Counter_as_number = { | |
0, /* nb_add */ | |
0, /* nb_subtract */ | |
0, /* nb_multiply */ | |
0, /* nb_divide */ | |
0, /* nb_remainder */ | |
0, /* nb_divmod */ | |
0, /* nb_power */ | |
Counter_Neg, /* nb_negative */ | |
Counter_Pos, /* nb_positive */ | |
Counter_Abs, /* nb_absolute */ | |
Counter_Nonzero, /* nb_nonzero */ | |
Counter_Invert, /* nb_invert */ | |
0, /* nb_lshift */ | |
0, /* nb_rshift */ | |
0, /* nb_and */ | |
0, /* nb_xor */ | |
0, /* nb_or */ | |
Counter_Coerce, /* nb_coerce */ | |
Counter_Int, /* nb_int */ | |
Counter_Long, /* nb_long */ | |
Counter_Float, /* nb_float */ | |
Counter_Oct, /* nb_oct */ | |
Counter_Hex, /* nb_hex */ | |
}; | |
/* type methods */ | |
static PyObject * | |
Counter_increment(self, args) | |
PyObject *self, *args; | |
{ PyObject *result = NULL; | |
long default_value = 1; | |
if (PyArg_ParseTuple(args, "|i:incr", &default_value)) | |
if (Counter_value(self) + default_value < Counter_value(self)) | |
PyErr_SetString(counter_error, "overflow"); | |
else { | |
Counter_value(self) += default_value; | |
result = Py_None; | |
Py_INCREF(result); | |
} | |
return result; | |
} | |
static PyObject * | |
Counter_decrement(self, args) | |
PyObject *self, *args; | |
{ PyObject *result = NULL; | |
long default_value = 1; | |
if (PyArg_ParseTuple(args, "|i:decr", &default_value)) | |
if (Counter_value(self) - default_value > Counter_value(self)) | |
PyErr_SetString(counter_error, "underflow"); | |
else { | |
Counter_value(self) -= default_value; | |
result = Py_None; | |
Py_DECREF(result); | |
} | |
return result; | |
} | |
/* Method table */ | |
static PyMethodDef Counter_methods[] = { | |
{"incr", Counter_increment, METH_VARARGS}, | |
{"decr", Counter_decrement, METH_VARARGS}, | |
{NULL, NULL}, | |
}; | |
/* Callback routines */ | |
static PyObject * | |
Counter_GetAttr(self, attrname) | |
PyObject *self; | |
char *attrname; | |
{ | |
return Py_FindMethod(Counter_methods, self, attrname); | |
} | |
static PyObject * | |
Counter_Repr(self) | |
PyObject *self; | |
{ PyObject *result = NULL; | |
char buf[25]; | |
sprintf(buf, "%d", Counter_value(self)); | |
return PyString_FromString(buf); | |
} | |
/* Type definition */ | |
/* remember the forward declaration above, this is the real definition */ | |
static PyTypeObject Counter_Type = { | |
PyObject_HEAD_INIT(&PyType_Type) | |
0, | |
"counter", | |
sizeof(Counter), | |
0, | |
(destructor)Counter_dealloc, | |
0, | |
(getattrfunc)Counter_GetAttr, | |
0, | |
0, | |
(reprfunc)Counter_Repr, | |
&Counter_as_number, | |
/* the rest are NULLs */ | |
}; | |
/* Python constructor */ | |
static PyObject * | |
Counter_new(self, args) | |
PyObject *self, *args; | |
{ PyObject *result = NULL; | |
long value = 0; /* default initial value */ | |
if (PyArg_ParseTuple(args, "|i", &value)) | |
result = Counter_NEW(value); | |
return result; | |
} | |
/* Module functions */ | |
static PyMethodDef methods[] = { | |
{"counter", Counter_new, METH_VARARGS}, | |
{NULL, NULL}, | |
}; | |
/* Module init function */ | |
void initcounter() | |
{ PyObject *m, *d; | |
m = Py_InitModule("counter", methods); | |
d = PyModule_GetDict(m); | |
/* initialize module variables/constants */ | |
#if PYTHON_API_VERSION >= 1007 | |
counter_error = PyErr_NewException("counter.error", NULL, NULL); | |
#else | |
counter_error = Py_BuildValue("s", "counter.error"); | |
#endif | |
PyDict_SetItemString(d, "error", counter_error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment