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


Автор: Nastya 23.3.2005, 16:20
Специалисты по питону, подскажите одну такую вешь.
Есть некотрый клас, написанный на С++, надо иметь возможность в програме из питоны, создавать объекты этого класса и/или вызывать его методы.
Что для этого надо сделать.
Обязательно ли для этого на базе класса создавать COM-объект.
Плиз, помогите

Автор: skalex 23.3.2005, 16:58
Попробуйте посмотреть вот здесь: http://docs.python.org/ext/ext.html

Автор: Void 27.3.2005, 11:19
Можно посмотреть также в сторону http://www.boost.org/libs/python/doc/index.html - довольно удобная библиотека для связывания Python и C++.

Автор: Nastya 5.4.2005, 10:52
спасибо за ссылочки.
Я использую ActivePython 2.4.
Проблема, нтеграции его в С++.
Задача приблезительно такая: есть с++ класс, есть его объет. У обякта есть метод. который по строке текста запускает интепритатор питона.
Причем в этой строке текста надо иметь возможность вызывать методы и самого этого класса
Вот код
Код


#include <Python.h>
//#pragma comment(lib,"python24_d.lib");
//С++ структура, пытаемся подключить

static PyObject*
 emb_Set(PyObject *self, PyObject *args)
 {
    char *key, *value;
     if(!PyArg_ParseTuple(args, "ss", &key, &value))
        return NULL;
     // do something with the C++ class here
     // how the get the class instance pointer?
     Py_INCREF(Py_None);
    return Py_None;
 }

 static PyMethodDef EmbMethods[] = {
     {"Set", emb_Set, METH_VARARGS, "Sets the given variable."},
     {NULL, NULL, 0, NULL}
 };




class MyClass  
{

public:
    int i;
   char ch50[50];

   MyClass(int x, char* y)
   {
       i=x;
       strcpy(ch50,y);
   }
   int GetI() {return i; }
   

   void runPhitonScriptMethod(char* script)
   {
       Py_Initialize();
       PyObject *m = Py_InitModule("test", EmbMethods);
       PyObject *c_api_object = PyCObject_FromVoidPtr((void *)this, NULL);
       if (c_api_object)
       {
         PyModule_AddObject(m, "MyObj", c_api_object);
         PyRun_SimpleString(script);
       }
       Py_Finalize();
   }

};

//Надо попытаться 





int main( int argc, char **argv )
{
        // Инициализировать Питон

   /*     Py_Initialize();

        //
        // Встроить функцию в Питон
        //
        
       Py_InitModule("emb", EmbMethods);


    P(
                "import emb"
                "\nprint"
                "\nprint 'Начало!'"
                "\nj=99"
    );

    P(
           "\nfor i in range(10):\n"
                "\tprint i,\n"
                "\tprint j\n"
                "\nemb.hello()"

    );

        Py_Finalize();*/

        MyClass obj(5,"Vision Master");
        obj.runPhitonScriptMethod
            (
                "import test"
                "\nj =99"
                "\nfor x in range(10):\n"
                "\tprint x,\n"
                "\tprint j\n"
                "\tprint test.MyObj.GetI()\n"
              );
        getch();
}


результат выдает следующий
0 99
Traceback (most recent call last):
File "<string>", line 6, in ?
AttributeError: 'PyCObject' object has no attribute 'GetI'
[6597 refs]

Т.е. метода моего он по прежнему не знает, тоже самое и со совйством (например i). если метод делаю виртуальным ситуация не меняется.

Я только начинаю с этим разбиратся, так что вполне возможно код бреждовый, но может хоть намекнете, как это по человечески делается smile

Автор: Nastya 5.4.2005, 11:34
А, еще один интересный момент.
Когда я выполняю строку
Код

"import MyTestModule"
"\nhelp('modules MyTestModule')"

Извеняюсь но косательно последнего примера, я модуль вместо test, назвала MyTestModule, что бы ни скем не дублировать названия smile
Так вот, когда я пытаюсь получить информацию про мой модуль, получаю пустой список. Т.е. модуль он находит, а вот толи класса, то ли его методов не видит smile

Автор: Nastya 5.4.2005, 15:38
Судя по всему мою проблему без bost или SWIG не решить smile
Void будь человеком, объясни рсским по белому что это и с чем это едят,
или дай ссылку на РУССКОЕ объяснение, а то я чего-то слабо сейчас соображаю smile

Автор: Nastya 5.4.2005, 16:38
И еще boost::python где можно скачать.
Или я не правильно ищу, но на http://www.boost.org/libs/libraries.htm нашло только документацию.

Автор: Void 6.4.2005, 16:33
Цитата(Nastya @ 5.4.2005, 15:38)
Судя по всему мою проблему без bost или SWIG не решить smile
Void будь человеком, объясни рсским по белому что это и с чем это едят,

С удовольствием, хотя я сам занимался этим только на уровне поиграться.

Приведенный пример с использованием Boost.Python будет выглядет так:
Код

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

#pragma comment(lib,"python24.lib")
#pragma comment(lib, "boost_python.lib")

namespace python = boost::python;

static PyObject* emb_Set(PyObject *self, PyObject *args)
{
    char *key, *value;
    if(!PyArg_ParseTuple(args, "ss", &key, &value))
        return NULL;
    // do something with the C++ class here
    // how the get the class instance pointer?
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef EmbMethods[] = {
    {"Set", emb_Set, METH_VARARGS, "Sets the given variable."},
    {NULL, NULL, 0, NULL}
};

class MyClass
{
public:
    int i;
    char ch50[50];
    MyClass(int x, char* y)
    {
        i = x;
        strcpy(ch50, y);
    }
    int GetI() {return i; }
    void runPythonScriptMethod(char* script)
    {
        using namespace python;
        // оборачиваем PyObject*, который возвращает Py_InitModule
        object module(handle<>(borrowed(Py_InitModule("test", EmbMethods))));
        // экспортируем this
        object MyObj(this);
        // добавляем this под именем "MyObj" в пространство имен модуля
        // метод ptr() возвращает PyObject* на экспортированный нами в Python объект
        PyModule_AddObject(module.ptr(), "MyObj", MyObj.ptr());
        PyRun_SimpleString(script);
    }
};

int main( int argc, char **argv)
{
    Py_Initialize();
    // экспортируем класс MyClass
    // Python должен быть инициализирован к этому моменту!
    python::class_<MyClass>("MyClass",
            python::init<int, char*>() // объявляем сигнатуру конструктора
        )
        .def("GetI", &MyClass::GetI) // экспортируем метод GetI
    ;
        MyClass obj(5, "Vision Master");
        obj.runPythonScriptMethod
        (
                "import test"
                "\nj =99"
                "\nfor x in range(10):\n"
                "\tprint x,\n"
                "\tprint j\n"
                "\tprint test.MyObj.GetI()\n"
        );
    Py_Finalize();
        getch();
}

Работает так:
Код

0 99
5
1 99
5
2 99
5
3 99
5
4 99
5
5 99
5
6 99
5
7 99
5
8 99
5
9 99
5

Объяснить что-то еще я вряд ли смогу, если будут вопросы или проблемы - попробуем разобраться smile
Цитата(Nastya @ 5.4.2005, 16:38)
И еще boost::python где можно скачать.
Или я не правильно ищу, но на http://www.boost.org/libs/libraries.htm нашло только документацию

Отдельного дистрибутива нет, там много зависимостей от остального кода Boost. Лучше всего целиком скачать Boost (http://sourceforge.net/project/showfiles.php?group_id=7586 - 8.46 Мб). Я попробовал выдрать библиотеку прилагаемой утилиткой bcp - получилось 880 Кб (RAR). Могу переслать, но как оно будет собираться и будет ли вообще - гарантировать не могу.

Автор: Katsura 11.8.2010, 18:37
Цитата

object MyObj(this);


В этой строке создается копия объекта this, и если объект MyObj будет изменен в питон-скрипте, то эти изменения не повлияют на this. Так вот - как передать ссылку именно на this объект, а не на его копию?

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