【问题标题】:Python C-API access String constantsPython C-API 访问字符串常量
【发布时间】:2015-08-16 20:20:00
【问题描述】:

我想使用 python 的 C-API 实现我为 C 语言编写的 python 库。在 python 中,我可以在我的模块中声明“常量”,只需声明:

RED = "red"   # Not really a constant, I know
BLUE = "blue" # but suitable, nevertheless

def solve(img_h):
    # Awesome computations
    return (RED, BLUE)[some_flag]

这些常量随后由模块提供的函数返回。我在 C 中做同样的事情时遇到了一些麻烦。这是我到目前为止得到的:

PyMODINIT_FUNC
PyInit_puzzler(void)
{
    PyObject* module = PyModule_Create(&Module);
    (void) PyModule_AddStringConstant(module, "BLUE",   "blue");
    (void) PyModule_AddStringConstant(module, "RED",    "red");
    return module;
}

PyObject* solve(PyObject* module, PyObject* file_handle)
{
    // Do some awesome computations based on the file
    // Involves HUGE amounts of memory management, thus efficient in C
    // PROBLEM: How do I return the StringConstants from here?
    return some_flag ? BLUE : RED;
}

我已经标记了有问题的部分。在我使用PyModule_AddStringConstant(module, "FOO", "foo"); 将字符串常量添加到模块后,我如何才能从我的方法中将它们实际返回为PyObject*?退货时是否需要增加 ref-counter?

【问题讨论】:

    标签: python c interface python-c-api


    【解决方案1】:

    由于PyModule_AddStringConstant(module, name, value) 将常量添加到模块中,它应该可以从模块的字典中获得,可以通过PyModule_GetDict(module) 获取。然后,您可以使用 PyDict_GetItemString(dict, key) 通过其字典访问模块中的任何属性,这就是您可以从模块中访问常量的方式(在它们定义之后):

    // Get module dict. This is a borrowed reference.
    PyObject* module_dict = PyModule_GetDict(module);
    
    // Get BLUE constant. This is a borrowed reference.
    PyObject* BLUE = PyDict_GetItemString(module_dict, "BLUE");
    
    // Get RED constant. This is a borrowed reference.
    PyObject* RED = PyDict_GetItemString(module_dict, "RED");
    

    要将其与您的 solve() 函数结合起来,您需要类似于:

    PyObject* solve(PyObject* module, PyObject* file_handle)
    {
        // Do some awesome computations based on the file
        // Involves HUGE amounts of memory management, thus efficient in C
    
        // Return string constant at the end.
        PyObject* module_dict = PyModule_GetDict(module);
        PyObject* constant = NULL;
        if (some_flag) {
            // Return BLUE constant. Since BLUE is a borrowed 
            // reference, increment its reference count before 
            // returning it.
            constant = PyDict_GetItemString(module_dict, "BLUE");
            Py_INCREF(constant);
        } else {
            // Return RED constant. Since RED is a borrowed 
            // reference, increment its reference count before 
            // returning it.
            constant = PyDict_GetItemString(module_dict, "RED");
            Py_INCREF(constant);
        }
    
        // NOTE: Before you return, make sure to release any owned
        // references that this function acquired. `module_dict` does
        // not need to be released because it is merely "borrowed".
    
        // Return the constant (either BLUE or RED) as an owned
        // reference. Whatever calls `solve()` must make sure to
        // release the returned reference with `Py_DECREF()`.
        return constant;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 2012-09-19
      • 1970-01-01
      相关资源
      最近更新 更多