простая функция c ++ и Boost python

Я построил это .so

#include <vector>

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

extern "C"
{
    // A function adding two integers and returning the result
    int SampleAddInt(int i1, int i2)
    {
        return i1 + i2;
    }

    // A function doing nothing ;)
    void SampleFunction1()
    {
        // insert code here
    }

    // A function always returning zero
    int SampleFunction2()
    {
        // insert code here

        return 0;
    }

    char const* greet()
    {
        return "hello, world";
    }
}

#include <iostream>
#include <string>

class hello
{
public:
    hello(const std::string& country)
    {
        this->country = country;
    }
    std::string greet() const
    {
        return "Hello from " + country;
    }
private:
    std::string country;
};

// A function taking a hello object as an argument.
std::string invite(const hello& w)
{
    return w.greet() + "! Please come soon!";
}

boost::python::tuple HeadAndTail(boost::python::object sequence)
{
    return make_tuple(sequence[0], sequence[-1]);
}

namespace py = boost::python;

BOOST_PYTHON_MODULE(hello_ext)
{
    using namespace boost::python;

    def("greet", greet);
    def("SampleAddInt", SampleAddInt);
    def("HeadAndTail", HeadAndTail);

    // Create the Python type object for our extension class and define __init__ function.
    boost::python::class_<hello>("hello", init<std::string>())
    .def("greetclass", &hello::greet)  // Add a regular member function.
    .def("invite", invite)  // Add invite() as a regular function to the module.
    ;

    def("invite", invite); // Even better, invite() can also be made a member of module!!!
}

Связал его с boost_python.

Затем в python я говорю: (с правильным путем к .so)

from ctypes import cdll
mydll = cdll.LoadLibrary('libHelloWorldPythonCpp.so')

#    import hello_ext

print mydll.greet()
vec = [-4, -2, 0, 2, 4]
print vec
print mydll.HeadAndTail(vec)

Однако я получаю странное значение, когда вызываю mydll.greet() из

-2015371328

Закомментированный код import hello_ext выдает ошибку, если я удалю комментарий ImportError: No module named hello_ext.

тем не мение

print mydll.SampleAddInt(6, 3)

Работает, но я не могу получить доступ к остальной части кода, например invite HeadAndTail и т. Д. Например

AttributeError: /home/idf/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release/libHelloWorldPythonCpp.so: undefined symbol: HeadAndTail

Если я перееду

boost::python::tuple HeadAndTail(boost::python::object sequence)
{
    return make_tuple(sequence[0], sequence[-1]);
}

внутри внешнего "C", то вроде работает. Однако затем я получаю сообщение об ошибке, когда передаю его vec:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
    execfile(filename, namespace)
  File "/home/idf/.spyder2/.temp.py", line 17, in <module>
    print mydll.HeadAndTail(vec)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1
>>> 

Я сделал

idf@C55t-A:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ readelf -Ws libHelloWorldPythonCpp.so | grep -i sample
   118: 0000000000008430     2 FUNC    GLOBAL DEFAULT   11 SampleFunction1
   120: 0000000000008440     3 FUNC    GLOBAL DEFAULT   11 SampleFunction2
   234: 0000000000008410     4 FUNC    GLOBAL DEFAULT   11 SampleAddInt
idf@C55t-A:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ 

И даже

idf@C55t-A:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ readelf -Ws libHelloWorldPythonCpp.so | grep -i head  
   230: 0000000000008560   483 FUNC    GLOBAL DEFAULT   11 _Z11HeadAndTailN5boost6python3api6objectE
idf@C55t-A:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ 

Итак, HeadAndTail, похоже, покалечен.

  1. Что мне не хватает в случае приветствия и т. Д.?
  2. Почему при импорте hello_ext возникает ошибка?
  3. Как мне вызвать HeadAndTail, который выглядит как c ++
  4. Какой тип является boost :: python :: object sequence в Python?
  5. Как мне вызвать функцию "greetclass" внутри класса?

РЕДАКТИРОВАТЬ:

Я только что скачал это

https://github.com/TNG/boost-python-examples

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


person Ivan    schedule 01.04.2015    source источник


Ответы (1)


С моей стороны это довольно глупо.

Хорошо, вот проблемы

  1. Я использую IDE spyder, не устанавливая в качестве рабочего каталога путь к файлу .so. При запуске из командной строки, вероятно, существуют сложные вещи типа PYTHONPATH, которые могут работать, но имея .so в том же каталоге, из которого запускается файл .py.
  2. Тебе не нужно ничего из этого from ctypes import cdll mydll = cdll.LoadLibrary дерьма. Вероятно, назовите свой .so таким же именем, которое вы даете в BOOST_PYTHON_MODULE (same_name_as_lib_name). Итак, если ваша библиотека называется hello.so, поместите привет внутри BOOST_PYTHON_MODULE (). Затем jus произнесите import hello, а затем вызовите такие функции, как print hello.greet()
  3. Мне вообще не нужно было говорить внешнюю "C".
person Ivan    schedule 02.04.2015