LINUX.ORG.RU

Boost::python::import не импортируется модуль

 , ,


1

1

Добрый вечер всем!

Никак не могу разобраться с выполнением python кода из с++.

Задача следующая. Пишем свой модуль для python. Потом в c++ коде выполняем некий python код, использующий этот модуль. Потом надо преобразовать python объекты в c++ объекты.

Вот код:

/// pytest.cpp                                                                                                                                                                                                                                 
/// build: g++ -std=c++1y -fPIC -I/usr/include/python3.4 -lboost_python -lpython3.4m pytest.cpp                                                                                                                                                
/// bould: g++ -std=c++1y -fPIC -I/usr/include/python3.4 -lboost_python-py34 -lpython3.4m pytest.cpp                                                                                                                                           

#include <string>
#include <iostream>
#include <boost/python.hpp>

using namespace boost::python;

int main() {
  try {
    Py_Initialize();
    object main_module = import("__main__");
    object main_namespace = main_module.attr("__dict__");

    // Тут import os нормально отработал                                                                                                                                                                                                       
    object tstObj = exec("print('This is Python code...')\n"
                         "import os\n"
                         "print(os.getcwd())\n",
                          main_namespace);


    // А тут import mymodule не импортирует:                                                                                                                                                                                                   
    object testThree = exec("import mymodule\n"
                            "obj = mymodule.cppClass('i am a string member of cppClass')\n"
                            "obj.print()\n"
                            "\n",
                            main_namespace);

    // Тоже не катит                                                                                                                                                                                                                           
    object mymodObj = import("mymodule");

    // Note that at this time you must not call Py_Finalize() to stop the interpreter. This may be fixed in a future version of boost.python.                                                                                                  
    // http://www.boost.org/doc/libs/master/libs/python/doc/html/tutorial/tutorial/embedding.html                                                                                                                                              
    // Py_Finalize();                                                                                                                                                                                                                          

  } catch(error_already_set const &) {
    if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {
      // handle ZeroDivisionError specially                                                                                                                                                                                                    
    } else {
      // print all other errors to stderr                                                                                                                                                                                                      
      PyErr_Print();
    }
  }
}

$ g++ -std=c++1y -fPIC -I/usr/include/python3.4 -lboost_python -lpython3.4m pytest.cpp && ./a.out
This is Python code...
/home/samson/cppPyhton
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named 'mymodule'

$ python
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymodule
>>> obj = mymodule.cppClass('i am a string member of cppClass')
8cppClass::cppClass(std::string)
>>> obj.print()
cppClass::print(): i am a string member of cppClass

import os выполняется нормально, а import mymodule - нет. Модуль mymodule создан и нормально импортируется из python:

Что я не так делаю? Как правильно сделать import?

ps: на всякий случай код модуля тут:
http://pastebin.com/L8VPvZbf
http://pastebin.com/QTqgxLc0

★★

Не уверен, но попробуй копнуть в сторону PYTHONPATH.

Kilte ★★★★★ ()
Ответ на: комментарий от Kilte

и как копнуть? надо из моего cpp кода указать пути к модулям? или что?

samson ★★ ()
Ответ на: комментарий от Kilte

Как настроить интерпретатор питона из c++ кода, что бы он видел этот модуль?

samson ★★ ()
Ответ на: комментарий от samson

Вообще по идее если в текущей рабочей директории есть этом модуль, то всё должно работать, о чём свидетельствует первый пост. Почему в твоём коде это не так, я могу только догадываться. Можно попробовать указать PYTHONPATH:

PYTHONPATH=/path/to/module/directory <your-command>

Или ещё один вариант, в код добавить такие строки:

import sys
sys.path.append('/your-path')
import mymodule

Ну или в конце-концов, опакетить через setuptools и поставить в систему/виртуальное окружение.

Kilte ★★★★★ ()
Ответ на: комментарий от Kilte

Так работает! И с PYTHONPATH и если в скрипт добавить...

Походу при создании интерпретатора в C++ не передается в PYTHONPATH текущая директория.

СенькюВериМач!

samson ★★ ()
Ответ на: комментарий от Kilte

Еще вопрос в догонку.

Как мне извлечь указатель на pyton функцию pyFunc(), да еще и вызвать ее???

    Py_Initialize();
    object main_module = import("__main__");
    object main_namespace = main_module.attr("__dict__");

    object tstObj = exec("import sys, os\n"
                         "sys.path.append(os.getcwd())\n",
                         main_namespace);

    object testTwo = exec_file("test.py", main_namespace);

    /* object mymodObj = import("mymodule"); */

    /* импортируем в C++ строку: */
    std::string s = extract<std::string>(main_module.attr("strA"));
    std::cout << s << std::endl;

    /* Как мне извлечь указатель на pyton функцию, да еще и вызвать ее??? */

# test.py

import sys, os
sys.path.append(os.getcwd())

import mymodule
obj = mymodule.cppClass('i am a string member of cppClass')
obj.print()

strA = "python string"

def pyFunc():
    print('python: pyFunc()');
    return "pyFuncResult"

samson ★★ ()
Ответ на: комментарий от samson

Это уже не ко мне, я к сожалению плюсов совсем не знаю.

Kilte ★★★★★ ()
Ответ на: комментарий от samson

Видел. Я подписан на питоновский тег. Как уже сказал, если бы знал плюсы, то помог. Максимум, что могу посоветовать — почитать документацию. Наверняка там есть ответ на этот вопрос. Если нет, то можно нагуглить примеры использования Boost::python. Не думаю, что это так сложно.

Kilte ★★★★★ ()
Ответ на: комментарий от Kilte

Документацию какраз и читаю. Вопросы конечно же еще остались. Примеров нашел кучу, но все немного не о том, что надо мне в примерах не нашел...

Что касается именно этого топика - вопрос закрыт, спасибо Kilte.

Не хотелось засорять форум, поэтому и написал тут.

samson ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.