c++ 和 Boost python 简单函数

标签 c++ python-2.7 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]);
}

在 extern "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. 如何调用似乎是 c++ 的 HeadAndTail
  4. Python 中的 boost::python::object 序列是什么类型?
  5. 如何在类中调用函数“greetclass”?

编辑:

我刚刚下载了这个

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

一切都编译并且似乎运行良好。我不明白我做错了什么,但当我发现时我会发布答案。

最佳答案

这对我来说很愚蠢。

好的,问题来了

  1. 我正在使用 spyder IDE,但没有将工作目录设置为 .so 的路径。如果从命令行运行,可能有复杂的 PYTHONPATH 类型的东西可以工作,但在运行 .py 文件的同一目录中有 .so。
  2. 您不需要这些 from ctypes import cdll mydll = cdll.LoadLibrary 废话。可能将您的 .so 命名为您在 BOOST_PYTHON_MODULE(same_name_as_lib_name) 中提供的相同名称。因此,如果您的库名为 hello.so,请将 hello 放在 BOOST_PYTHON_MODULE() 中。然后只需说 import hello 然后调用像 print hello.greet()
  3. 这样的函数
  4. 我根本不需要说 extern "C"。

关于c++ 和 Boost python 简单函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29398642/

相关文章:

c++ - 如何提高C++中的多线程性能

python - 关于boost-python : dyld: Symbol not found: _PyBaseObject_Type

python - 在 boost.python 中使用它时不能在我的抽象类中使用纯虚函数

c++ - 解析格式化输入时划分单词的问题

c++ - 将大字符串发送到套接字

python - Python 3 中的 writerow 总是在原始行之间写一个空行,Python2 工作得很好。为什么?

python-2.7 - 在一行中转储 pickle 时,我还需要 file.close() 吗?

Python:如果不存在则赋值

python - Boost.Python 示例,Windows 7 x64, "ImportError: DLL load failed: The specified module could not be found."

c++ - Socket C++ 程序编译成功在运行时崩溃