15

我一直在尝试在 C++ 应用程序中嵌入不同的脚本语言,目前我正在尝试 Stackless Python 3.1。我已经尝试了几个教程和示例,我能找到的很少,尝试从应用程序运行一个简单的脚本。

Py_Initialize();

FILE* PythonScriptFile = fopen("Python Scripts/Test.py", "r");
if(PythonScriptFile)
{
    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py");
    fclose(PythonScriptFile);
}

Py_Finalize();

出于某种奇怪的原因,运行这段代码会导致访问冲突:

    PyRun_SimpleFile(PythonScriptFile, "Python Scripts/Test.py");

我在网上搜索了其他有类似问题的人,只找到了一个。他们唯一的解决方案是一种只有在旧版本的 Python 中才有可能的解决方法:创建一个 python 文件对象并将该 python 文件对象中的返回FILE*PyRun_SimpleFile. 但是,此类函数调用不可用,Python 3.1 API 从文件描述符创建文件对象并返回文件描述符,但该PyRun_SimpleFile函数仍然需要FILE*.

我不知道如何从文件中运行任何脚本,没有手动将整个文件加载到内存中并将其作为一个巨大的字符串运行,当然不是一个实用的解决方案。

是什么赋予了?如果 API 出现内部错误,我该如何完成此任务?

更新:我已经设法从源代码构建 Stackless Python 3.1,但崩溃仍然完全没有改变,尽管使用了相同的 C 运行时库。我的项目和 Stackless Python 3.1 源代码都是使用 Visual Studio 2010 的 C++ 编译器和 C 运行时构建的。我不再知道什么可以解决这个问题,除了修改 Python 以使用文件名而不是 FILE*。另一个可怕的解决方法。

4

7 回答 7

14

这适用于我在 Python 3 上:

 PyObject *obj = Py_BuildValue("s", "test.py");
 FILE *file = _Py_fopen_obj(obj, "r+");
 if(file != NULL) {
     PyRun_SimpleFile(file, "test.py");
 }

我希望它会有用。

于 2012-03-09T05:17:04.830 回答
13

我遇到了类似的崩溃并做了以下事情:

   PyObject* PyFileObject = PyFile_FromString("test.py", "r");
   PyRun_SimpleFileEx(PyFile_AsFile(PyFileObject), "test.py", 1);

请注意,这是在python 2.7中。我不知道 API 在 3.x 中是否发生了变化。

于 2011-09-14T04:38:07.480 回答
5

您的代码在我安装的 Python 2.6 版本上正常工作。我还从源代码构建了 stackless 3.1.2,它工作正常。这是 Ubuntu 10.04 上的 g++ 4.4.3。如果您在 Windows 上,您可能需要检查无堆栈和您的代码是否针对相同的 C 运行时构建。

于 2010-09-06T23:53:43.473 回答
3

这听起来像是 API 不匹配的问题。如果您的代码和 Python 运行时是使用不同的编译器甚至不同的编译器选项编译的,那么访问 FILE* 可能会导致访问冲突。您能否再次检查您是否正确构建了 C 代码?

您提到您将 Python 嵌入到您的 C++ 应用程序中。请记住,Python 是 C 代码,编译为 C 代码。也许这就是问题的根源?

于 2010-09-06T22:55:22.583 回答
0

如果您使用 VC 2010 构建测试,您肯定会遇到问题 - VC9 (VS 2008) 和 VC10 (VS 2010) 具有通常需要的相互不兼容的支持 DLL(实现 printf、文件 i/o 等)。如果它们包含标准库,则不能混合它们,python 构建会这样做。

您始终可以选择使用 gcc(例如 Cygwin 或 mingw)或下载 Visual Studio 2008 express,这对于 Python 嵌入的实验应该可以正常工作。我在标准的 Python 2.7.6 版本中都使用了这两个版本。

于 2014-06-03T16:57:23.073 回答
0

那么这个解决方案呢:

Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("execfile(\"ex30.py\")");
Py_Finalize();

ex30.py我正在运行的 python 脚本的名称在哪里。

于 2015-11-06T10:17:42.580 回答
0

下面的代码将执行 test.py 模块。Python 将在路径集中搜索模块。所以应该先处理路径。

Py_Initialize();

string path = "Python Scripts/";

//Set the path
PyRun_SimpleString("import sys");
string str = "sys.path.append('" + path + "')";
PyRun_SimpleString(str.c_str());

//Dont use test.py as it actually searches sub module test>>py
PyObject * moduleName = PyUnicode_FromString("test");
PyObject * pluginModule = PyImport_Import(moduleName);

if (pluginModule == nullptr)
{
    PyErr_Print();
    return "";
}

//Do the executions here

//clean up
Py_DECREF(moduleName);
Py_DECREF(pluginModule);
Py_DECREF(transformFunc);
Py_DECREF(result);

Py_Finalize();
于 2018-03-15T11:27:43.980 回答