2013-04-10 34 views
9

Tôi đang cố gắng tạo ví dụ Boost.Python đầu tiên của mình.Cần trợ giúp để bắt đầu với Boost.Python

#include <iostream> 
#include <boost/python.hpp> 

using namespace boost::python; 


class Hello { 

public: 
    std::string greet() { 
     std::cout << "Hello World" << std::endl; 
    } 
}; 


BOOST_PYTHON_MODULE(hello) 
{ 
    class_<Hello>("Hello") 
     .def("greet", &Hello::greet); 
} 

int main() { 
    std::cout << "Boost.Python Test" << std::endl; 
    Hello hello; 
    hello.greet(); 
    return 0; 
} 

CHỈNH SỬA: Tiêu đề phát triển Python bị thiếu, như @cdhowie đã chỉ ra. Tôi đã tìm thấy và bao gồm các tệp tiêu đề bắt buộc. Bây giờ người liên kết đang khiếu nại:

10:43:58 **** Build of configuration BoostPythonTest-DPar for project BoostPythonTest 

**** 
make all 
Building file: ../src/BoostPythonTest.cpp 
Invoking: GCC C++ Compiler 
/usr/local/bin/g++-4.7 -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -I/usr/include -I/usr/local/Cellar/gcc/4.7.2/gcc/include/c++/4.7.2 -O0 -g3 -p -pg -Wall -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"src/BoostPythonTest.d" -MT"src/BoostPythonTest.d" -o "src/BoostPythonTest.o" "../src/BoostPythonTest.cpp" 
Finished building: ../src/BoostPythonTest.cpp 

Building target: libBoostPythonTest-DPar.dylib 
Invoking: MacOS X C++ Linker 
/usr/local/bin/g++-4.7 -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/lib/python3.3/config-3.3m -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/lib -L/usr/local/Cellar/boost/1.51.0/lib -std=c++11 -Xlinker -ldl -framework CoreFoundation -lpython3.3m -dynamiclib -o "libBoostPythonTest-DPar.dylib" ./src/BoostPythonTest.o -lpython3.3m -lboost_python-mt -lpython3.3 
Undefined symbols for architecture x86_64: 
    "boost::python::detail::init_module(PyModuleDef&, void (*)())", referenced from: 
     _PyInit_hello in BoostPythonTest.o 
ld: symbol(s) not found for architecture x86_64 
collect2: error: ld returned 1 exit status 
make: *** [libBoostPythonTest-DPar.dylib] Error 1 

Tôi đã liên kết với -lpython3.3m -lboost_python-mt -lpython3.3 - còn gì khác nữa?

EDIT: Tôi nghĩ rằng tôi đã liên kết với mọi thứ có danh sách python3.3-config. Liên kết vẫn không hoạt động do thiếu biểu tượng.

Trả lời

12

Khi lỗi liên kết cụ thể này xảy ra, thường là kết quả của việc xây dựng ứng dụng dựa trên một phiên bản Python, chẳng hạn như tệp tiêu đề Python 3.x, trong khi thư viện boost_python được xây dựng dựa trên phiên bản khác biệt, chẳng hạn như 2. x.

Trong boost/python/module_init.hpp, các init_module hàm có chữ ký sau khi xây dựng chống Python 3.x:

PyObject* boost::python::detail::init_module(PyModuleDef&, void(*)()); 

và chữ ký sau khi xây dựng chống Python 2.x:

PyObject* boost::python::detail::init_module(char const* name, void(*)()); 

Như thể được nhìn thấy trong các implementation, chỉ có một trong các chức năng sẽ có mặt trong thư viện Boost.Python. Vì vậy, với thư viện Boost.Python đang được liên kết, và trình liên kết chỉ phàn nàn về việc không thể giải quyết chức năng 3.x init_module, thì rất có khả năng thư viện Boost.Python được xây dựng dựa trên Python 2. x phiên bản, trong khi mã ứng dụng đã được xây dựng dựa trên các tệp tiêu đề Python 3.x. Bạn có thể xác minh điều này bằng cách bán các ký hiệu của thư viện Boost.Python và kiểm tra chữ ký init_module.

Để giải quyết vấn đề này, hãy tạo ứng dụng có cùng phiên bản Python mà từ đó Boost.Python đã được tạo. Trong trường hợp này, hoặc là:

  • Tạo ứng dụng với các tệp tiêu đề Python 2.x và liên kết với các thư viện Python 2.x.
  • Xây dựng Boost.Python chống lại Python 3.x.This tài liệu mô tả các bước để xây dựng Boost, và tài liệu this đi vào chi tiết cho Boost.Python. Nó có thể là cần thiết để cung cấp một cách rõ ràng Python thực thi mà từ đó Boost.Python sẽ xây dựng chống lại trong quá trình bootstrap bằng cách sử dụng đối số --with-python.
+0

Tôi tin rằng bạn đã chẩn đoán vấn đề chính xác. Tôi đang cố gắng để xây dựng Boost.Python chống lại Python 3.3. – clstaudt

+0

Khi tôi cố gắng xây dựng Boost.Python tôi nhận được [lỗi sau] (https://gist.github.com/anonymous/5433641). 'gcc.link.dll ../../../../bin.v2/libs/python/build/gcc-4.2.1/debug/libboost_python.dylib ld: warning: không tìm thấy thư mục cho tùy chọn ' -L/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Phiên bản/3.3/lib/python3.3/config ' ld: tùy chọn không xác định: -R collect2: ld trả về 1 trạng thái thoát' Điều gì đang xảy ra ở đây? – clstaudt

+1

@cls: Nếu bạn đang sử dụng phiên bản Apple của chuỗi công cụ GCC, sau đó thử chỉ định toolset là 'darwin' thay vì' gcc'. –

6

Bạn đang thiếu các tiêu đề phát triển Python. Bản phân phối Linux của bạn nên có một gói cho chúng. (Ví dụ: python-dev trên Debian hoặc Ubuntu.)

+1

Cảm ơn bạn đã chỉ ra lỗi. Nhưng tôi đang sử dụng OSX, bất kỳ ý tưởng làm thế nào để có được các tiêu đề? Homebrew dường như không có công thức 'python-dev'. – clstaudt

+1

@cls Tôi không sử dụng OS X nên tôi không thể cung cấp bất kỳ lời khuyên nào ở đó. Có lẽ ai đó khác có thể. – cdhowie

+0

Các tiêu đề được tìm thấy, nhưng có các vấn đề liên kết và tôi muốn làm ví dụ. – clstaudt

2

Bạn đang xây dựng thư viện dùng chung, vì đó là mô-đun nhị phân Python. Đối với điều đó, bạn cần chia sẻ hoặc -namnamic (kiểm tra các tài liệu) và bạn không nên có một hàm main().

Hơn nữa, nếu điều đó không hiệu quả và bạn vẫn gặp lỗi trình liên kết, hãy sử dụng "objdump -T --demangle/path/to/lib" để tìm ra các ký hiệu chứa thư viện và thư viện có chứa nhu cầu. Ngoài ra kiểm tra đầu ra của "ldd", liệt kê các đối tượng chia sẻ phụ thuộc. Điều này sẽ cung cấp cho bạn một gợi ý mà thư viện hoặc thư viện để liên kết.

Trên hệ thống của mình, tôi cũng có một chương trình có tên là "python-config" và "python2.7-config". Kiểm tra xem bạn có một cái gì đó tương tự, bởi vì kịch bản này biết những thư viện để liên kết ít nhất cho python. Một công cụ tương tự là pkg-config, đó là tổng quát hơn và có thể cung cấp thông tin để tăng cường.

+0

'python3.3-config' cho tôi một số đường dẫn và cờ mà tôi đã thêm vào, nhưng không có hiệu lực (xem các cuộc gọi ở trên). 'otool' (dường như là tương đương OSX của' objdump') cho tôi ví dụ '$ otool -T libboost_python-mt.dylib libboost_python-mt.dylib: Mục lục (0 mục) chỉ mục ký hiệu chỉ mục mô-đun'. 'ldd' dường như không tồn tại trên OSX. – clstaudt

1

Bạn cũng phải liên kết với Boost.System, cũng như mọi thư viện khác được đề cập bởi trình liên kết. Ngoài ra, hãy thử các trình biên dịch khác, chẳng hạn như Clang (https://svn.boost.org/trac/boost/ticket/7536), đi kèm với XCode (Latest Clang location in XCode 4.5). Ngoài ra, hãy thử đăng makefile của bạn. Một nỗ lực khác sẽ được sử dụng bjam/b2 thay vì thực hiện.

2

Không chắc chắn đây có phải là cách để làm điều đó hay không, nhưng có vẻ như PY_VERSION_HEX được đặt sai. gì sẽ xảy ra nếu bạn

#define PY_VERSION_HEX 0x03300000 

trước bao gồm các tiêu đề Boost.Python trong BoostPythonTest.cpp của bạn?

+0

Đây là một bình luận, không phải là một câu trả lời. –

Các vấn đề liên quan