Boost-Python: сбой при выполнении скрипта из файла - PullRequest
4 голосов
/ 14 февраля 2012

Когда мое консольное приложение пытается выполнить boost :: python :: exec_file (), оно зависает на секунду, а затем вылетает.

Может без проблем выполнить boost :: python :: exec.

Я попытался не использовать тогда повышение привязок и выполнение непосредственно из Python API, но происходит то же самое, он немного зависает, а затем вылетает:

FILE *file = fopen("test.py", "r+");
PyRun_SimpleFile(file, "test");

Так что я думаю, что это проблема с Python API, так как это то, на что ссылается boost.python?

Я использую общую сборку Boost.Python и ссылаюсь на предварительно скомпилированную версию 32-битной библиотеки Python 3.2.2 (libpython32.a), и я компилирую с MinGW 4.6 через QtCreator на Windows 7

Это мой main.cpp:

#include <Python.h>
#include <boost/python.hpp>
#include <iostream>

namespace python = boost::python;

int main( int argc, char ** argv ) {
    try {
        // File path
        std::string filepath;
        if(argv[1] != NULL) {
            filepath = argv[1];
        }

        // Initialize the interpreter
        Py_Initialize();
        std::cout << "Using Python " << Py_GetVersion() << std::endl;

        // Create the python environment
        python::object main = python::import("__main__");
        python::object global(main.attr("__dict__"));

        //python::exec("print('hello world')", global, global);
        python::object result = python::exec_file("test.py", global, global);

    } catch (python::error_already_set const &) {
        python::handle_exception();
    }
}

Это файл сценария, который я пытаюсь выполнить (test.py):

print("hello world")

Мой файл .pro выглядит так:

#Application config
TEMPLATE = app
CONFIG += console
CONFIG -= qt

#Path and environment info
PYTHONTEST_ROOT = $$PWD
PYTHONTEST_BIN = $$PYTHONTEST_ROOT /bin
PYTHONTEST_LIB = $$PYTHONTEST_ROOT /lib
PYTHONTEST_INCLUDE = $$PYTHONTEST_ROOT /include
PYTHONTEST_TMP = $$PYTHONTEST_ROOT /tmp

MOC_DIR = $$PYTHONTEST_TMP/mocs
OBJECTS_DIR = $$PYTHONTEST_TMP/objs

#Includes and dependencies
INCLUDEPATH += C:/Python32/include
INCLUDEPATH += C:/Boost_1_48_0

#Build info
Debug {
    win32 {
        #Libs
        LIBS += -LC:/Python32/libs -lpython32
        LIBS += -LC:/Boost_1_48_0/stage/lib -lboost_python-mgw46-mt-d-1_48.dll

        #Build config
        DESTDIR = $$PYTHONTEST_BIN/debug/win32/
        TARGET = pythontest_d
    }
    unix {
    }
    macx {
    }
}

Release {
    win32 {
        #Libs
        LIBS += -LC:/Python32/libs -lpython32
        LIBS += -LC:/Boost_1_48_0/stage/lib -lboost_python-mgw46-mt-1_48.dll

        #Build config
        DESTDIR = $$PYTHONTEST_BIN/release/win32/
        TARGET = pythontest
    }
    unix {
    }
    macx {
    }
}

#Source code
SOURCES += main.cpp
HEADERS +=

Все это, кажется, работает нормально, нет ошибок компиляции или ссылки, хотя я получаю некоторые предупреждения:

In file included from c:\Boost_1_48_0/boost/python/object/make_instance.hpp:9,
from c:\Boost_1_48_0/boost/python/object/make_ptr_instance.hpp:8,
from c:\Boost_1_48_0/boost/python/to_python_indirect.hpp:11,
from c:\Boost_1_48_0/boost/python/converter/arg_to_python.hpp:10,
from c:\Boost_1_48_0/boost/python/call.hpp:15,
from c:\Boost_1_48_0/boost/python/object_core.hpp:14,
from c:\Boost_1_48_0/boost/python/args.hpp:25,
from c:\Boost_1_48_0/boost/python.hpp:11,
from ..\PythonTest\main.cpp:2:
c:\Boost_1_48_0/boost/python/object/instance.hpp:14: warning: type attributes ignored after type is already defined

EDIT Теперь это не объясняет и не решает сбой, но я могу обойти его, используя мою собственную функцию чтения и просто передавая boost :: python :: exec вывод. тогда мне не нужно использовать exec_file или PyRun_SimpleFile

#include <fstream>

std::string read_file(std::string const &filepath)
{
    std::string output;
    std::ifstream file;
    file.open(filepath.c_str());
    if(file.is_open()){
        while(!file.eof()){
            std::string line;
            std::getline(file,line);
            output += line.append("\n");
        }
    }
    file.close();
    return output;
}
...