Skip to content

Instantly share code, notes, and snippets.

@alaingalvan
Created August 10, 2017 13:17
Show Gist options
  • Save alaingalvan/db63858c35ff156f4d9723b33a4e867f to your computer and use it in GitHub Desktop.
Save alaingalvan/db63858c35ff156f4d9723b33a4e867f to your computer and use it in GitHub Desktop.
Python C++ bindings code sample from docs
/*
* 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