如何在 C++ 中修复 PyImport_Import(python35.dll 中的异常)
How to fix PyImport_Import in C++ (Exception in python35.dll)
我正在尝试一个非常基本的 "hello world" 程序,它应该在我的 C++ 控制台应用程序中嵌入一个 python 脚本,但它在 pModule = PyImport_Import(pName);
失败并出现未指定的异常 "Access violation reading location ..."
我已经能够 运行 PyRun_SimpleFile()
用于没有定义的 python 脚本和 returns,但对于我未来的应用程序,我需要一个 python returns 的方法,所以 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
好吧,我认为您的代码中缺少一些说明,例如 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
初始化。
我正在尝试一个非常基本的 "hello world" 程序,它应该在我的 C++ 控制台应用程序中嵌入一个 python 脚本,但它在 pModule = PyImport_Import(pName);
失败并出现未指定的异常 "Access violation reading location ..."
我已经能够 运行 PyRun_SimpleFile()
用于没有定义的 python 脚本和 returns,但对于我未来的应用程序,我需要一个 python returns 的方法,所以 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
好吧,我认为您的代码中缺少一些说明,例如 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
初始化。