在3.3加载Python模块时,用什么代替PyString_AsString?

15 投票
2 回答
22582 浏览
提问于 2025-04-17 22:51

我正在尝试在我的一个C++程序中加载一个Python函数,使用了这个函数

char * pyFunction(void)
{
    char *my_result = 0;
    PyObject *module = 0;
    PyObject *result = 0;
    PyObject *module_dict = 0;
    PyObject *func = 0;
    PyObject *pArgs = 0;

    module = PyImport_ImportModule("testPython");
    if (module == 0)
    {
        PyErr_Print();
        printf("Couldn't find python module");
    }
    module_dict = PyModule_GetDict(module); 
    func = PyDict_GetItemString(module_dict, "helloWorld"); 

    result = PyEval_CallObject(func, NULL); 
    //my_result = PyString_AsString(result); 
    my_result = strdup(my_result);
    return my_result;
}

我应该用什么来代替PyString_AsString呢?

2 个回答

3

如果你之前用过 PyString_AsString 来获取一个可以在C语言中使用的 const char* 表示形式,而你知道这个对象是一个 str 类型的字符串,那么在Python 3中,你只需要使用 PyUnicode_AsUTF8 就可以了:

    func = PyDict_GetItemString(module_dict, "helloWorld"); 

    result = PyEval_CallObject(func, NULL); 
    const char* my_result = PyUnicode_AsUTF8(result); 
23

根据你从 helloWorld() 函数返回的类型,结果可能会有所不同,所以最好先检查一下。

如果返回的是 str(在 Python 2 中是 unicode),你需要对它进行编码。具体用什么编码取决于你的使用场景,但我这里用的是 UTF-8:

if (PyUnicode_Check(result)) {
    PyObject * temp_bytes = PyUnicode_AsEncodedString(result, "UTF-8", "strict"); // Owned reference
    if (temp_bytes != NULL) {
        my_result = PyBytes_AS_STRING(temp_bytes); // Borrowed pointer
        my_result = strdup(my_result);
        Py_DECREF(temp_bytes);
    } else {
        // TODO: Handle encoding error.
    }
}

如果返回的是 bytes(在 Python 2 中是 str),你可以直接获取这个字符串:

if (PyBytes_Check(result)) {
    my_result = PyBytes_AS_STRING(result); // Borrowed pointer
    my_result = strdup(my_result);
}

另外,如果你收到的不是字符串的对象,你可以使用 PyObject_Repr()PyObject_ASCII()PyObject_Str() 或者 PyObject_Bytes() 来转换它。

所以最后你可能想要的结果是这样的:

if (PyUnicode_Check(result)) {
    // Convert string to bytes.
    // strdup() bytes into my_result.
} else if (PyBytes_Check(result)) {
    // strdup() bytes into my_result.
} else {
    // Convert into your favorite string representation.
    // Convert string to bytes if it is not already.
    // strdup() bytes into my_result.
}

撰写回答