包装期望C动态回调的C函数

时间:2012-12-30 04:39:40

标签: python python-c-api cpython

我正在尝试编写一个libedit包装器(一种替代readline的BSD,API略有不同),并且有一种方法可以将命名函数添加到C API中。

例如在C:

static unsigned char show_help(EditLine *e, int ch) {
    printf("Help");
}

el = el_init(argv[0], stdin, stdout, stderr);
el_set(el, EL_ADDFN, "help",  "This is help", show_help);
el_set(el, EL_BIND, "\?", "help", NULL);

我调用el_set添加一个函数,然后再绑定该函数。

我找不到允许我将EL_ADDFN包装成动态绑定Python方法的好方法。我可以创建一堆预先命名的C函数并将它们全部包装到python方法中,但我更愿意尽可能地模拟C API。

有没有办法调用EL_ADDFN并确定它正在调用哪个python方法?

1 个答案:

答案 0 :(得分:0)

试试这个:一个单一的处理函数(我将在下面描述)。包装EL_ADDFN以便它记录name到python函数的映射,但始终使用一个处理函数。包装EL_BIND,以便记录字符到函数名的映射。您的处理函数应查找字符中的ch参数以命名映射,然后查找名称以进行函数映射,然后调用该函数。 (如果必须在BIND之前调用ADDFN,则可以创建一个ch函数映射并直接在BIND包装器中填充它。)

在伪C中:

const char *chmap[256];  // initialize to zero
struct hashtable *namemap;  // up to you to find a
                            // hashtable implementation that
                            // will take const char * and map to
                            // PyObject * (function object);

static unsigned char python_func(EditLine *e, int ch) {
    const char *name = chmap[ch];
    // check for errors
    PyObject *func = lookup(namemap, name);
    // check for errors

    PyObject *editline = convert(e); // or whatever you have
    PyObject *result = PyObject_CallFunctionObjArgs(func, NULL);
    // check result, convert to unsigned char, and return
}

因此,ADDFN包装器填充哈希表,BIND运算符填充chmap。