简体   繁体   English

C ++和Boost python简单函数

[英]c++ and Boost python simple function

I built this .so 我建立了这个.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!!!
}

Linked it with boost_python. 将其与boost_python链接。

In python, I then say: (with the correct path to the .so) 然后在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)

However I get a strange value when I call mydll.greet() of 但是,当我调用mydll.greet()时,得到一个奇怪的值

-2015371328

The import hello_ext code that is commented out gives an error if I remove the comment, ImportError: No module named hello_ext . 如果删除注释, ImportError: No module named hello_ext注释掉的import hello_ext代码将产生错误, ImportError: No module named hello_ext

However 然而

print mydll.SampleAddInt(6, 3)

Works, but I can't access the rest of the code like invite HeadAndTail etc. For example 可以,但是我无法访问其余代码,例如, invite HeadAndTail等。例如

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

If I move 如果我移动

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

inside the extern "C" then it seems to work. 在外部“ C”内部,那么它似乎可以工作。 However then I get an error when I pass it vec: 但是,当我通过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
>>> 

I did a 我做了一个

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$ 

And even 乃至

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$ 

So HeadAndTail seems to be mangled. 因此HeadAndTail似乎被扭曲了。

  1. What am I missing in the greet etc case? 在打招呼等情况下我缺少什么?
  2. Why does import hello_ext give an error? 为什么导入hello_ext会给出错误?
  3. How do I call HeadAndTail which appears to be c++ 我如何调用似乎是c ++的HeadAndTail
  4. What type is boost::python::object sequence in Python? Python中的boost :: python :: object序列是什么类型?
  5. How do I call the function "greetclass" inside the class? 我如何在类内部调用函数“ greetclass”?

EDIT: 编辑:

I just downloaded this 我刚刚下载了这个

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

and everything compiles and seems to run fine. 一切都可以编译并且运行正常。 I don't understand what I am doing wrong, but when I find out I will post an answer. 我不明白自己在做什么错,但是当我发现问题时会给出答案。

This is pretty dumb on my part. 就我而言,这真是愚蠢。

Ok, here are the problems 好,这里有问题

  1. I am using spyder IDE without setting the working directory to the path of the .so. 我在不将工作目录设置为.so路径的情况下使用spyder IDE。 If run from the command line, there are probably complicated PYTHONPATH type of things that could work, but having .so in the same directory from where your run the .py file works. 如果从命令行运行,则可能存在复杂的PYTHONPATH类型的事情,但是在运行.py文件的目录中存在.so。
  2. You don't need any of this from ctypes import cdll mydll = cdll.LoadLibrary crap. 您不需要from ctypes import cdll mydll = cdll.LoadLibrary废话中获取任何信息。 Probably name your .so the same name you give in BOOST_PYTHON_MODULE(same_name_as_lib_name). 可能将您的.so命名为您在BOOST_PYTHON_MODULE(same_name_as_lib_name)中输入的相同名称。 So if your lib is named hello.so, put hello inside of BOOST_PYTHON_MODULE(). 因此,如果您的库名为hello.so,则将hello放入BOOST_PYTHON_MODULE()中。 Then jus say import hello and then call the functions like print hello.greet() 然后,jus说import hello ,然后调用诸如print hello.greet()类的函数。
  3. I didn't need to say extern "C" at all. 我根本不需要说“ C”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM