原文:https://docs.python.org/dev/extending/extending.html

“使用C或C++扩展Python(二)-从C调用python”

/*
spamcall.c
compile:gcc -fPIC -shared -I /usr/include/python3.5m/ spamcall.c -o spamcall.so
usage:
>>> import spamcall
>>> def func(a):
        print(a)
>>> spamcall.set_calllback(func)
>>> spamcall.call_it(123)
123
reference:https://docs.python.org/dev/extending/extending.html
*/
#include <Python.h>

static PyObject *my_callback = NULL;    // def func(a):

static PyObject *
my_set_callback(PyObject *dummy, PyObject *args)
{
    PyObject *result = NULL;
    PyObject *temp;

    if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
        if (!PyCallable_Check(temp)) {
            PyErr_SetString(PyExc_TypeError, "parameter must be callable");
            return NULL;
        }
        Py_XINCREF(temp);
        Py_XDECREF(my_callback);
        my_callback = temp;
        Py_INCREF(Py_None);
        result = Py_None;
    }
    return result;
}

static PyObject *
my_call_it(PyObject *dummy, PyObject *args)
{
    int arg;
    PyObject *arglist;
    PyObject *result;


    arg = 123;
    if (!PyArg_ParseTuple(args, "i", &arg))
        return NULL;
    arglist = Py_BuildValue("(i)", arg);
    result  = PyObject_CallObject(my_callback, arglist);
    Py_DECREF(arglist);
    if (result == NULL)
        return NULL;
    Py_DECREF(result);

    Py_RETURN_NONE;    // Py_INCREF(Py_None); return Py_None;
}

static PyMethodDef SpamMethods[] = {
    {"set_callback", my_set_callback, METH_VARARGS, "set a callback"},
    {"call_it", my_call_it, METH_VARARGS, "call it"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef spammodule = {
    PyModuleDef_HEAD_INIT,
    "spamcall",   /* name of module */
    "Example module that creates an extension type.", /* module documentation, may be NULL */
    -1,       /* size of per-interpreter state of the module,or -1 if the module keeps state in global variables. */
    SpamMethods
};

PyMODINIT_FUNC
PyInit_spamcall(void)
{
    PyObject *m;

    m = PyModule_Create(&spammodule);
    if (m == NULL)
        return NULL;
    return m;
}