2015-04-01 94 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」。