【问题标题】:Wrapping a C function that expect C dynamic callbacks包装期望 C 动态回调的 C 函数
【发布时间】:2012-12-30 04:39:40
【问题描述】:

我正在尝试围绕 libedit(一个 BSD 替代 readline 的 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 方法?

【问题讨论】:

    标签: python python-c-api cpython


    【解决方案1】:

    试试这个:一个单一的处理函数(我将在下面描述)。包装 EL_ADDFN 以便它记录名称到 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。

    【讨论】:

      猜你喜欢
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多