Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost.python 
:(
    Опции темы
mrgloom
Дата 27.4.2012, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



рассмотрим самый простой пример 

Код

# test.py
def my_sum(x,y):
    print "Hello World!"
    return x*x+y



как мне вызвать этот код? из с++?

т.е. я должен получить что то типа

код C++
Код

int sum= py.my_sum(3,5);


документацию пробовал читать, но что то там сложно и непонятно понадобится ли интерпретатор питона конечной программе?
PM MAIL   Вверх
boostcoder
Дата 27.4.2012, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mrgloom @  27.4.2012,  12:42 Найти цитируемый пост)
непонятно понадобится ли интерпретатор питона конечной программе?

разумеется.

Цитата(mrgloom @  27.4.2012,  12:42 Найти цитируемый пост)
boost.python

это тут не при чем.
boost.python делает обратное. т.е. код написанный на С/С++ позволяет использовать в пайтон.

читай это: http://docs.python.org/extending/embedding.html
ну мегапростое решение.
Код

#include <Python.h>

int main(int argc, char *argv[]) {
  Py_Initialize();

  static const char *program = ""
    "def my_sum(x,y):\n"
    "\tprint \"Hello World!\"\n"
    "\treturn x*x+y\n";

  PyRun_SimpleString(program);

  Py_Finalize();
  return 0;
}


Это сообщение отредактировал(а) boostcoder - 27.4.2012, 13:50
PM WWW   Вверх
mrgloom
Дата 27.4.2012, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



Цитата(boostcoder @  27.4.2012,  13:20 Найти цитируемый пост)
разумеется.


ну я про что то типа py2exe, т.е. не надо ставить интерпретатор на другой машине, где потом будет запускаться программа.
т.е. что я примерно хочу это взять и каким либо образом запаковать мои .py файлы и нужное для них из интерпретатора в .lib и затем в мою с++ программу только подключить либу и заголовок с описанием класса с функциями или просто функций.
и потом из кода вызывать примерно так
Код

#include "Py_lib_header.h"
my_py_class a;
int sum= a.my_sum(3,4);

ну или без класса, а просто функцию вызвать.

Цитата

ну мегапростое решение.
код C++
#include <Python.h>
int main(int argc, char *argv[]) {
  Py_Initialize();
  static const char *program = ""
    "def my_sum(x,y):\n"
    "\tprint \"Hello World!\"\n"
    "\treturn x*x+y\n";
  PyRun_SimpleString(program);
  Py_Finalize();
  return 0;
}

ну так и что будет являться результатом этой операции?
мне то надо, как я писал выше, аргументы передать в с++ функцию и результат из неё получить, а тут как я понял просто строка интерпретатору отсылается на выполнение?

Это сообщение отредактировал(а) mrgloom - 27.4.2012, 14:13
PM MAIL   Вверх
boostcoder
Дата 27.4.2012, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



ссылку читай. там показано как из плюсов передавать аргументы в пайтон, и получать результаты обратно.
PM WWW   Вверх
mrgloom
Дата 27.4.2012, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



да, понял. секция 5.3.

хмм получается что для каждого типа возвращаемого значения надо будет написать свою функцию? 
call_python_func(char* module,char* func_name)
или можно как то на месте узнавать тип возвращаемого значения?


да и буст похоже умеет это делать в обе стороны 
http://stackoverflow.com/questions/215752/...ata-back-to-cpp

пытаюсь переписать с примера, но непонятно как передаются параметры просто в строке через пробел?
Код

#include <Python.h>

int
main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pArg, *pResult;
    int i;

    Py_Initialize();
    pName = PyString_FromString("MyModule.py");
    /* Error checking of pName left out as exercise */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, "MyFunc");
        /* pFunc is a new reference */

        if (pFunc) {
            pArgs = PyTuple_New(0);
            pArg = PyString_FromString("some parameter")  //как передавать параметры? строкой?
            /* pArg reference stolen here: */
            PyTuple_SetItem(pArgs, 0, pArg);
            pResult = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pResult != NULL) {
                printf("Result of call: %s\n", PyString_AsString(pResult));
                Py_DECREF(pResult);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function");
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load module");
        return 1;
    }
    Py_Finalize();
    return 0;
}


вот нашел еще пример, но тут опять же никаких значений не передается и не возвращается.
Код

// call_function.c - A sample of calling 
// python functions from C code
// 
#include <Python.h>

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

    if (argc < 3) 
    {
        printf("Usage: exe_name python_source function_name\n");
        return 1;
    }

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyString_FromString(argv[1]);

    // Load the module object
    pModule = PyImport_Import(pName);

    // pDict is a borrowed reference 
    pDict = PyModule_GetDict(pModule);

    // pFunc is also a borrowed reference 
    pFunc = PyDict_GetItemString(pDict, argv[2]);

    if (PyCallable_Check(pFunc)) 
    {
        PyObject_CallObject(pFunc, NULL);  //хотя вот тут можно передавать вместо NULL параметры, только в каком виде?
    } else 
    {
        PyErr_Print();
    }

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);

    // Finish the Python Interpreter
    Py_Finalize();

    return 0;
}

PM MAIL   Вверх
mrgloom
Дата 27.4.2012, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



вроде разобрался, но все равно не работает.

Код

int call_python_func(char* module,char* func_name)
{
    PyObject *pName, *pModule, *pDict, *pFunc;
    PyObject *pArgs, *pValue;
    int ret;

    Py_Initialize();
    pName = PyString_FromString(module);
    /* Error checking of pName left out */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) 
    {
        pFunc = PyObject_GetAttrString(pModule, func_name);
        /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) 
        {
            pArgs = Py_BuildValue("5.0","15.0");  //вообще должны передаваться в функцию
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) 
            {
                // Set return value
                ret = (int)PyFloat_AsDouble(pValue);
                printf("Result of call: %ld\n", PyInt_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else 
            {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return -1;
            }
        }
        else 
        {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"\n", func_name);
            return -1;
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else 
    {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"\n", module);
    }
    Py_Finalize();

    return ret;
}
int main(int argc, char *argv[])
{
    cout<<call_python_func("test","myadd");
    getchar();
    return 0;
}


на питоне файл
Код

def myadd(a,b):
    f= a*a+b
    print(f)
    print("hell0 add")
    return f
    
    myadd(3,6)


пишет что не может найти myadd
    
PM MAIL   Вверх
boostcoder
Дата 27.4.2012, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mrgloom @  27.4.2012,  17:08 Найти цитируемый пост)
пишет что не может найти myadd

покажи какое именно сообщение пишет.
PM WWW   Вверх
volatile
Дата 28.4.2012, 02:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(mrgloom @  27.4.2012,  17:08 Найти цитируемый пост)
   cout<<call_python_func("test","myadd");

Цитата(mrgloom @  27.4.2012,  17:08 Найти цитируемый пост)
пишет что не может найти myadd
     


Назовите ваш модуль другим именем. 
test - встроенный модуль, и там нет "myadd"
PM MAIL   Вверх
volatile
Дата 28.4.2012, 03:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Еще вот что заметил
Цитата(mrgloom @  27.4.2012,  17:08 Найти цитируемый пост)
pArgs = Py_BuildValue("5.0","15.0");  

это не правильно
Если вы хотите передать 2 дабла, то
Код

pArgs = Py_BuildValue("dd", 5.0, 15.0);
если 2 инта,то 
Код

pArgs = Py_BuildValue("ii", 5, 15);


Добавлено через 5 минут и 4 секунды
http://docs.python.org/release/1.5.2/ext/buildValue.html
PM MAIL   Вверх
mrgloom
Дата 28.4.2012, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



да спасибо, так работает, протестировал пока правда только на простой функции, а не на реальных файлах.
но все таки придется писать для каждого типа возвращаемого значения свою функцию?
и еще вопрос о прикручивании питона внутрь, наивным методом пока остановился вот на чем.
если собрать .exe с вышеобозначенным кодом и перенести на другой компьютер, то пишет 
python.dll не найден, ну доложил в папку dll и теперь пишет ImportError: No module named site.
дальше пока не знаю что делать.
PM MAIL   Вверх
boostcoder
Дата 28.4.2012, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mrgloom @  28.4.2012,  10:46 Найти цитируемый пост)
 пишет ImportError: No module named site.

потому что интерпретатор должен знать где лежит директория lib с библиотеками пайтона.
по умолчанию, он ищет ее в той же директории где лежит python.dll.

PM WWW   Вверх
mrgloom
Дата 28.4.2012, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



скопировал папку Lib, где находятся все .py теперь всё работает, я так понимаю что мне достаточно оставить в папке только те .py файлы которые вызывает моя программа?
и еще вопрос запаковать в .exe сразу это все сразу нельзя?
PM MAIL   Вверх
boostcoder
Дата 28.4.2012, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mrgloom @  28.4.2012,  11:11 Найти цитируемый пост)
мне достаточно оставить в папке только те .py файлы которые вызывает моя программа?

и их зависимости.
PM WWW   Вверх
mrgloom
Дата 28.4.2012, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



а как быть, если у меня класс и надо обратится к методу класса?  (в примере myadd3)

Код

class class_cl:
    def __init__(self):
        print("constructor")
    
    def myadd3(self,a):
        print(a)


Это сообщение отредактировал(а) mrgloom - 28.4.2012, 12:24
PM MAIL   Вверх
mrgloom
Дата 28.4.2012, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



хмм но теоретически даже если не получится вызывать метод класса, то наверно можно все self переменные сделать глобальными класс убрать и просто сделать список функций или я не вижу каких то подводных камней?

Это сообщение отредактировал(а) mrgloom - 28.4.2012, 13:03
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0628 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.