【问题标题】:How to fix PyImport_Import in C++ (Exception in python35.dll)如何在 C++ 中修复 PyImport_Import(python35.dll 中的异常)
【发布时间】:2019-05-31 13:47:34
【问题描述】:

我正在尝试一个非常基本的“hello world”程序,它应该在我的 C++ 控制台应用程序中嵌入一个 python 脚本,但它在 pModule = PyImport_Import(pName); 失败,出现未指定的异常“访问冲突读取位置...”

我已经能够为没有定义和返回的 python 脚本运行 PyRun_SimpleFile(),但是对于我未来的应用程序,我需要一个带返回的 python 方法,所以 PyRun_SimpleFile() 不是一个选项。

我的代码,基于this Introduction 是:

main.cpp

#include "stdafx.h"
#include <stdlib.h>
#include <Python.h>

int main(int argc, char *argv[])
{
    PyObject *pName, *pModule;
    PyObject *pFunc, *pValue;

    pName = PyUnicode_FromString("HelloWorld");
    pModule = PyImport_Import(pName);
    Py_XDECREF(pName);

    if (pModule)
    {
        pFunc = PyObject_GetAttrString(pModule, "getInteger");
        if (pFunc && PyCallable_Check(pFunc))
        {
            pValue = PyObject_CallObject(pFunc, NULL);
            printf_s("C: getInteger() = %ld\n", PyLong_AsLong(pValue));
            Py_XDECREF(pValue);
        }
        else
        {
            printf("ERROR: function getInteger()\n");
        }
        Py_XDECREF(pFunc);
    }
    else
    {
        printf_s("ERROR: Module not imported\n");
    }

    Py_XDECREF(pModule);

    Py_Finalize();
    return 0;
}

HelloWorld.py(在我的 VS2015 解决方案的调试位置):

def getInteger():
    print('Python function getInteger() called')
    c = 100*2
    return c

【问题讨论】:

    标签: c++ python-3.x python-embedding


    【解决方案1】:

    好吧,我相信您的代码中缺少一些说明,例如 Py_Initialize。我也会使用PyImport_ImportModule 而不是PyImport_Import。查看您可能正在尝试的这个序列:

    int main(int argc, char *argv[])
    {
        Py_SetPythonHome(L"path/to/python/folder");
        Py_Initialize();
        //PySys_SetArgv(argc, argv); //optional, argv must be wchar_t
        PyObject *pFunc, *pValue;
    
        pModule = PyImport_ImportModule("HelloWorld");
    
        if (pModule)
        {
            pFunc = PyObject_GetAttrString(pModule, "getInteger");
            if (pFunc && PyCallable_Check(pFunc))
            {
                pValue = PyObject_CallObject(pFunc, NULL);
                printf_s("C: getInteger() = %ld\n", PyLong_AsLong(pValue));
                Py_XDECREF(pValue);
            }
            else
            {
                printf("ERROR: function getInteger()\n");
            }
            Py_XDECREF(pFunc);
        }
        else
        {
            printf_s("ERROR: Module not imported\n");
        }
    
        Py_XDECREF(pModule);
    
        Py_Finalize();
        return 0;
    }
    

    如果还是不行,试试在PyInitialize后面加上这个:

    PyRun_SimpleString(
        "import os, sys \n"
        "sys.path.append(os.getcwd()) \n"
    );
    

    同样在PyInitialize之后,你可以检查它是否被Py_IsInitialized初始化。

    【讨论】:

    • 非常感谢!失踪的Py_Initialize 解决了!但是现在我被困在 Py_Finalize 的读取访问冲突上。对此也有什么想法吗?
    • 尽量不要Py_XDECREF(pModule)。删除这一行,看看它是否停止崩溃。
    • 不幸的是,这并没有改变它。但是我发现堆被破坏了,但我真的不知道在哪里?
    • 由于这与原来的问题无关,我决定开一个新的。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2016-06-02
    • 2017-09-24
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多