Python C-API访问字符串常量

5

我想使用Python的C-API将我编写的Python库实现为C语言。在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*?当我返回它们时,我需要增加引用计数吗?

1个回答

5

由于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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接