You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python C API在C++中解析Python返回字符串遇段错误求助

Python C API调用字符串返回值时出现段错误的解决思路

我在C++代码中使用Python C API调用Python编写的函数,目前能够解析Python返回的列表、字典,但在解析返回的字符串时出现了段错误。附上相关代码,恳请大家提供解决思路。

Python代码(hell.py)

import json

### 示例代码,需要返回该字符串
def get_json():
    
    res = '{"Hello": [2.3, 4.5, 7.8], "How": 0, "Why": "no"}' # 要返回的示例字典
    a = json.loads(res)
    print(a)

    l1 = json.dumps(a)   # 转为字符串
    return l1  # 返回该字符串

原C++代码(存在问题)

#define PY_SSIZE_T_CLEAN

#include</usr/include/python3.6/Python.h>
#include <bits/stdc++.h>

PyObject *mymodule = PyImport_ImportModule("hell");                         PyErr_Print();
PyObject *myfunc = PyObject_GetAttrString(mymodule, "get_json");          PyErr_Print();

PyObject *result1 = PyObject_CallObject(myfunc1, NULL);                     PyErr_Print();

char * buff = new char[100];
buff = PyByteArray_AsString(result1);

cout<<buff[0]<<endl; // 此处出现段错误

问题分析与修正方案

1. 变量名错误

原代码调用PyObject_CallObject时用了未定义的myfunc1,实际函数指针是myfunc,野指针调用直接触发内存错误。

2. 类型不匹配导致非法访问

PyByteArray_AsString仅适用于PyByteArray类型对象,但Python返回的是PyUnicode类型字符串(Python3默认字符串类型),用错函数会访问非法内存区域,引发段错误。

3. 内存泄漏

先new char[100]分配内存,随后直接将buff指向其他地址,导致之前的内存无法释放。

修正后的C++代码

#define PY_SSIZE_T_CLEAN

#include </usr/include/python3.6/Python.h>
#include <iostream>

int main() {
    // 必须初始化Python解释器,原代码遗漏此步骤
    Py_Initialize();
    if (!Py_IsInitialized()) {
        std::cerr << "Python初始化失败" << std::endl;
        return 1;
    }

    PyObject *mymodule = PyImport_ImportModule("hell");
    if (!mymodule) {
        PyErr_Print();
        Py_Finalize();
        return 1;
    }

    PyObject *myfunc = PyObject_GetAttrString(mymodule, "get_json");
    if (!myfunc || !PyCallable_Check(myfunc)) {
        PyErr_Print();
        Py_DECREF(mymodule);
        Py_Finalize();
        return 1;
    }

    // 修正变量名:myfunc1 → myfunc
    PyObject *result1 = PyObject_CallObject(myfunc, NULL);
    if (!result1) {
        PyErr_Print();
        Py_DECREF(myfunc);
        Py_DECREF(mymodule);
        Py_Finalize();
        return 1;
    }

    // 处理Python Unicode字符串:转为UTF-8编码的C字符串
    PyObject *utf8_bytes = PyUnicode_AsUTF8String(result1);
    if (!utf8_bytes) {
        PyErr_Print();
        Py_DECREF(result1);
        Py_DECREF(myfunc);
        Py_DECREF(mymodule);
        Py_Finalize();
        return 1;
    }
    const char *buff = PyBytes_AsString(utf8_bytes);
    if (buff) {
        std::cout << buff << std::endl;
    }

    // Python3.3+ 也可直接用以下方式,返回内存由Python管理
    // const char *buff = PyUnicode_AsUTF8(result1);
    // if (buff) std::cout << buff << std::endl;

    // 释放Python对象引用,避免内存泄漏
    Py_DECREF(utf8_bytes);
    Py_DECREF(result1);
    Py_DECREF(myfunc);
    Py_DECREF(mymodule);

    // 关闭Python解释器
    Py_Finalize();
    return 0;
}

额外注意事项

  • 必须调用Py_Initialize()初始化Python解释器,否则会出现未定义行为。
  • 所有创建的PyObject都要用Py_DECREF()释放引用,避免内存泄漏。
  • 每一步Python API调用后都要检查返回值是否为NULL,及时处理错误并释放资源。

内容的提问来源于stack exchange,提问作者ABD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:34:43