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

C++调用Python代码出现read access violation v was nullptr异常如何解决

C++调用Python触发空指针访问异常的原因与修复方案

触发原因

你遇到的读取访问冲突异常本质是PyObject_CallObject调用时传入的my_function为nullptr,空指针访问直接触发崩溃。导致my_function为空的核心诱因有两类:

  1. 模块导入失败:PyImport_ImportModule("PythonCode")返回空值,后续传入空指针调用PyObject_GetAttrString自然返回空
    具体可能的触发场景:
    • PythonCode.py文件不在程序运行的工作目录,也不在Python解释器默认的模块搜索路径中
    • PythonCode.py本身存在语法错误、依赖缺失问题,导入时触发内部错误
  2. 函数属性获取失败:模块导入成功,但PythonCode模块中不存在你传入的pName对应的全局函数
    具体可能的触发场景:
    • 传入的函数名拼写错误、大小写不匹配(Python函数名大小写敏感)
    • 目标函数定义在类/其他函数内部,不是模块的全局属性

另外你现有代码未对Python API的返回值做任何合法性校验,错误发生后仍继续执行后续逻辑,是直接触发崩溃的重要原因。

修复方案

  • 新增Python API返回值校验,每一步执行失败后打印错误并终止流程,避免空指针传递
  • 导入模块前先将当前目录加入Python的模块搜索路径,解决模块找不到的问题
  • 核对传入的函数名与Python文件中定义的函数名完全一致
  • 补充必要的资源释放逻辑,避免内存泄漏

修正后的参考代码

#include <Python.h>
#include <iostream>
#include <iomanip>
#define NOMINMAX
#include <Windows.h>
#undef NOMINMAX
#include <cmath>
#include <string>
// 修正原代码错误的头文件引用,<stream>应为<sstream>
#include <sstream>
#include <cstring>

using namespace std;

void CallProcedure(string pName)
{
    char* procname = new char[pName.length() + 1];
    std::strcpy(procname, pName.c_str());

    Py_Initialize();
    if (!Py_IsInitialized()) {
        cout << "Python解释器初始化失败" << endl;
        delete[] procname;
        return;
    }
    // 将当前目录加入模块搜索路径
    PyRun_SimpleString("import sys\nsys.path.append('.')");

    PyObject* my_module = PyImport_ImportModule("PythonCode");
    // 校验模块是否导入成功
    if (!my_module) {
        PyErr_Print();
        cout << "导入PythonCode模块失败" << endl;
        Py_Finalize();
        delete[] procname;
        return;
    }

    PyObject* my_function = PyObject_GetAttrString(my_module, procname);
    // 校验函数是否存在且可调用
    if (!my_function || !PyCallable_Check(my_function)) {
        PyErr_Print();
        cout << "获取函数" << pName << "失败,或该函数不可调用" << endl;
        Py_DECREF(my_module);
        Py_Finalize();
        delete[] procname;
        return;
    }

    PyObject* my_result = PyObject_CallObject(my_function, NULL);
    // 后续逻辑:处理返回值、释放Python对象、关闭解释器
    if (my_result) {
        // 按需处理返回结果
        Py_DECREF(my_result);
    } else {
        PyErr_Print();
    }

    // 资源释放
    Py_DECREF(my_function);
    Py_DECREF(my_module);
    Py_Finalize();
    delete[] procname;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:06:03