2015-04-01 53 views
1

我建这个是.soC++和Python的升压功能简单

#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链接它。

在蟒蛇,然后我说:(用正确的路径。所以)

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) 

的作品,但我不能访问代码的其余部分一样inviteHeadAndTail等。例如

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 
>>> 

我做了

[email protected]:~/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 
[email protected]:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ 

即使

[email protected]:~/Documents/BOOST_Python/HelloWorldPythonCpp/bin/Release$ readelf -Ws libHelloWorldPythonCpp.so | grep -i head 
    230: 0000000000008560 483 FUNC GLOBAL DEFAULT 11 _Z11HeadAndTailN5boost6python3api6objectE 
[email protected]:~/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 

,一切编译,似乎运行正常。我不明白我做错了什么,但是当我发现我会发表一个答案。

回答

0

这对我来说很愚蠢。

好了,这里有问题

  1. 我使用Spyder的IDE没有工作目录设置中的.so的路径。如果从命令行运行,可能有复杂的PYTHONPATH类型的东西可以工作,但将.so放在运行.py文件的同一目录下。
  2. 你不需要任何这from ctypes import cdll mydll = cdll.LoadLibrary废话。可能将您的.so命名为您在BOOST_PYTHON_MODULE(same_name_as_lib_name)中给出的同名。因此,如果您的lib名为hello.so,请将其放在BOOST_PYTHON_MODULE()中。然后理所当然地说import hello然后调用函数,如print hello.greet()
  3. 我根本不需要说extern“C”。