Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > скриптование C++


Автор: chaos 25.9.2008, 14:08
ДЕнь добрый! почитал тут мануал по QT 4. и нашел одну интересную весчь - QT Script.
с помощью нее можно выносить куски кода в скрипты что придает динамику приложению.
Вставл вопрос: есть ли что еще подобное(QT Script)  ?
вроде как в бусте есть boost::python, но если я не ошибюсь предназначен он для обратного: из питона юзать С++.
а я хочу из С++ юзать питон smile - те например из С++ программы передать какие-то данные скрипту, тот в свою очередь обработает как-то их и отдаст обратно.



Заранне благодарен за ответы smile

Автор: Daevaorn 25.9.2008, 14:35
Цитата(chaos @  25.9.2008,  15:08 Найти цитируемый пост)
но если я не ошибюсь предназначен он для обратного: из питона юзать С++.

ошибаетесь.

Автор: chaos 25.9.2008, 14:45
Daevaorn, а можно по подробнее.
хотелось бы увидеть типо такого примера: из С++ передать строку в питон-скрипт, тот с ней чото делает, и возвращает обратно.

Автор: xvr 25.9.2008, 15:01
Цитата(chaos @ 25.9.2008,  14:08)
ДЕнь добрый! почитал тут мануал по QT 4. и нашел одну интересную весчь - QT Script.
с помощью нее можно выносить куски кода в скрипты что придает динамику приложению.
Вставл вопрос: есть ли что еще подобное(QT Script)  ?

Есть. В Windows есть IActiveScript и Scripting host - позволяют использовать из своей программы любые установленные в системе скриптовые языки (по умолчанию JS и VBA)
В Linux есть куча сторонних библиотек с интерпретаторами (на вскидку - lua и JS от Mozzila, не помню как называется, тот же python и perl). Это все можно задействовать и под Виндами.

Цитата

вроде как в бусте есть boost::python, но если я не ошибюсь предназначен он для обратного: из питона юзать С++.
Не совсем - для интеграции своих C++ классов в python

Автор: chaos 25.9.2008, 15:04
Цитата(xvr @ 25.9.2008,  12:01)
Не совсем - для интеграции своих C++ классов в python

ну я так и хотел сказать smile
что касается IScriptEng... не подходит, тк нужно кросс. посмотрю в сторону луа, вроде много где слышал это слово
 smile

Автор: chaos 26.9.2008, 06:05
прочитал про луа, вроде ничего сложно, но почему-то душа лежит к питону smile
поковырялся с в boost::python и нашел скудный пример:

Код

// Copyright Stefan Seefeld 2005.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>

#include <boost/detail/lightweight_test.hpp>
#include <iostream>

namespace python = boost::python;

// An abstract base class
class Base : public boost::noncopyable
{
public:
  virtual ~Base() {};
  virtual std::string hello() = 0;
};

// C++ derived class
class CppDerived : public Base
{
public:
  virtual ~CppDerived() {}
  virtual std::string hello() { return "Hello from C++!";}
};

// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, python::wrapper<Base>
{
  virtual std::string hello() 
  {
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    // workaround for VC++ 6.x or 7.0, see
    // http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
    return python::call<std::string>(this->get_override("hello").ptr());
#else
    return this->get_override("hello")();
#endif
  }
};

// Pack the Base class wrapper into a module
BOOST_PYTHON_MODULE(embedded_hello)
{
  python::class_<BaseWrap, boost::noncopyable> base("Base");
}


void exec_test()
{
    std::cout << "registering extension module embedded_hello..." << std::endl;
    
  // Register the module with the interpreter
  if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
    throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
                 "builtin modules");

  std::cout << "defining Python class derived from Base..." << std::endl;
  
  // Retrieve the main module
  python::object main = python::import("__main__");
  
  // Retrieve the main module's namespace
  python::object global(main.attr("__dict__"));

  // Define the derived class in Python.
  python::object result = python::exec(
    "from embedded_hello import *        \n"
    "class PythonDerived(Base):          \n"
    "    def hello(self):                \n"
    "        return 'Hello from Python!' \n",
    global, global);

  python::object PythonDerived = global["PythonDerived"];

  // Creating and using instances of the C++ class is as easy as always.
  CppDerived cpp;
  BOOST_TEST(cpp.hello() == "Hello from C++!");

  std::cout << "testing derived class from C++..." << std::endl;
  
  // But now creating and using instances of the Python class is almost
  // as easy!
  python::object py_base = PythonDerived();
  Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;

  // Make sure the right 'hello' method is called.
  BOOST_TEST(py.hello() == "Hello from Python!");

  std::cout << "success!" << std::endl;
}

void exec_file_test(std::string const &script)
{
    std::cout << "running file " << script << "..." << std::endl;
    
    // Run a python script in an empty environment.
    python::dict global;
    python::object result = python::exec_file(script.c_str(), global, global);

    // Extract an object the script stored in the global dictionary.
    BOOST_TEST(python::extract<int>(global["number"]) ==  42);
    
    std::cout << "success!" << std::endl;
}

void exec_test_error()
{
    std::cout << "intentionally causing a python exception..." << std::endl;
    
    // Execute a statement that raises a python exception.
    python::dict global;
    python::object result = python::exec("print unknown \n", global, global);

    std::cout << "Oops! This statement should be skipped due to an exception" << std::endl;
}

int main(int argc, char **argv)
{
  BOOST_TEST(argc == 2);
  std::string script = argv[1];
  // Initialize the interpreter
  Py_Initialize();

  bool error_expected = false;
  
  if (
      python::handle_exception(exec_test)
      || python::handle_exception(boost::bind(exec_file_test, script))
      || (
          (error_expected = true)
          && python::handle_exception(exec_test_error)
      )

  )
  {
    if (PyErr_Occurred())
    {
        if (!error_expected)
            BOOST_ERROR("Python Error detected");
        PyErr_Print();
    }
    else
    {
        BOOST_ERROR("A C++ exception was thrown  for which "
                    "there was no exception translator registered.");
    }
  }
  
  // Boost.Python doesn't support Py_Finalize yet, so don't call it!
  return boost::report_errors();
}



это как раз то что я хочу smile но этого очень мало

Автор: xvr 26.9.2008, 10:11
Цитата(chaos @ 26.9.2008,  06:05)
прочитал про луа, вроде ничего сложно, но почему-то душа лежит к питону smile
поковырялся с в boost::python и нашел скудный пример:

Код

// Copyright Stefan Seefeld 2005.
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>

#include <boost/detail/lightweight_test.hpp>
#include <iostream>

namespace python = boost::python;

// An abstract base class
class Base : public boost::noncopyable
{
public:
  virtual ~Base() {};
  virtual std::string hello() = 0;
};

// C++ derived class
class CppDerived : public Base
{
public:
  virtual ~CppDerived() {}
  virtual std::string hello() { return "Hello from C++!";}
};

// Familiar Boost.Python wrapper class for Base
struct BaseWrap : Base, python::wrapper<Base>
{
  virtual std::string hello() 
  {
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
    // workaround for VC++ 6.x or 7.0, see
    // http://boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html#python.class_virtual_functions
    return python::call<std::string>(this->get_override("hello").ptr());
#else
    return this->get_override("hello")();
#endif
  }
};

// Pack the Base class wrapper into a module
BOOST_PYTHON_MODULE(embedded_hello)
{
  python::class_<BaseWrap, boost::noncopyable> base("Base");
}


void exec_test()
{
    std::cout << "registering extension module embedded_hello..." << std::endl;
    
  // Register the module with the interpreter
  if (PyImport_AppendInittab("embedded_hello", initembedded_hello) == -1)
    throw std::runtime_error("Failed to add embedded_hello to the interpreter's "
                 "builtin modules");

  std::cout << "defining Python class derived from Base..." << std::endl;
  
  // Retrieve the main module
  python::object main = python::import("__main__");
  
  // Retrieve the main module's namespace
  python::object global(main.attr("__dict__"));

  // Define the derived class in Python.
  python::object result = python::exec(
    "from embedded_hello import *        \n"
    "class PythonDerived(Base):          \n"
    "    def hello(self):                \n"
    "        return 'Hello from Python!' \n",
    global, global);

  python::object PythonDerived = global["PythonDerived"];

  // Creating and using instances of the C++ class is as easy as always.
  CppDerived cpp;
  BOOST_TEST(cpp.hello() == "Hello from C++!");

  std::cout << "testing derived class from C++..." << std::endl;
  
  // But now creating and using instances of the Python class is almost
  // as easy!
  python::object py_base = PythonDerived();
  Base& py = python::extract<Base&>(py_base) BOOST_EXTRACT_WORKAROUND;

  // Make sure the right 'hello' method is called.
  BOOST_TEST(py.hello() == "Hello from Python!");

  std::cout << "success!" << std::endl;
}

void exec_file_test(std::string const &script)
{
    std::cout << "running file " << script << "..." << std::endl;
    
    // Run a python script in an empty environment.
    python::dict global;
    python::object result = python::exec_file(script.c_str(), global, global);

    // Extract an object the script stored in the global dictionary.
    BOOST_TEST(python::extract<int>(global["number"]) ==  42);
    
    std::cout << "success!" << std::endl;
}

void exec_test_error()
{
    std::cout << "intentionally causing a python exception..." << std::endl;
    
    // Execute a statement that raises a python exception.
    python::dict global;
    python::object result = python::exec("print unknown \n", global, global);

    std::cout << "Oops! This statement should be skipped due to an exception" << std::endl;
}

int main(int argc, char **argv)
{
  BOOST_TEST(argc == 2);
  std::string script = argv[1];
  // Initialize the interpreter
  Py_Initialize();

  bool error_expected = false;
  
  if (
      python::handle_exception(exec_test)
      || python::handle_exception(boost::bind(exec_file_test, script))
      || (
          (error_expected = true)
          && python::handle_exception(exec_test_error)
      )

  )
  {
    if (PyErr_Occurred())
    {
        if (!error_expected)
            BOOST_ERROR("Python Error detected");
        PyErr_Print();
    }
    else
    {
        BOOST_ERROR("A C++ exception was thrown  for which "
                    "there was no exception translator registered.");
    }
  }
  
  // Boost.Python doesn't support Py_Finalize yet, so don't call it!
  return boost::report_errors();
}



это как раз то что я хочу smile но этого очень мало

А в boost\libs\python\doc не заглядывали? Там довольно много чего понаписано   smile 

Автор: chaos 26.9.2008, 11:56
Цитата(xvr @ 26.9.2008,  07:11)
А в boost\libs\python\doc не заглядывали? Там довольно много чего понаписано   smile

смотрел, не на столько глуп smile
там "99%" про то как интегрировать код С++ в питон. а мне это пока не очень нужно. Надо на оборот

Автор: xvr 26.9.2008, 20:28
Цитата(chaos @ 26.9.2008,  11:56)
Цитата(xvr @ 26.9.2008,  07:11)
А в boost\libs\python\doc не заглядывали? Там довольно много чего понаписано   smile

смотрел, не на столько глуп smile
там "99%" про то как интегрировать код С++ в питон. а мне это пока не очень нужно. Надо на оборот

Если мне не изменяет мой склероз, то там где то есть пример, в котором не только интегрировали C++ в python, но и исполняли строку на pyton прямо из C++ программы. Если и этого недостаточно, то я уже и не знаю, что еще нужно  smile 

Автор: azesmcar 30.9.2008, 16:07
Не совсем понятно в 4ем собственно проблема. Ска4ай и установи питон или ТСЛ, там есть либы.. линкуй и пользуйся.

Автор: chaos 6.10.2008, 08:58
вообще разбираюсь потихоньку с бустом smile
есть определенные успехи.
1. научился вызывать методы класса опредлеленнго в питоне.
2. научился дергать методы определенные С++ программе из питона.

есть небольшой примерчик с гуи smile по нажатию кнопики добавляется в лист данные. данные конечно же из питона. те "питон обрабатывает" нажатие кнопки.
кому интересно могу выложить

Автор: Alek86 6.10.2008, 11:16
лучше выложи в любом случае...
кому через полгода понадобится - в гугле или по поиску форума найдет smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)