需要帮助开始使用Boost.Python

时间:2013-04-10 15:03:45

标签: c++ python boost boost-python

我正在尝试构建我的第一个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;
}
编辑:正如@cdhowie指出的那样,缺少Python开发标题。我找到并包含了所需的头文件。现在链接器正在抱怨:

   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

我已经链接到-lpython3.3m -lboost_python-mt -lpython3.3 - 还缺少什么?

编辑:我认为我已经链接到python3.3-config列出的所有内容。由于缺少符号,链接仍然无效。

5 个答案:

答案 0 :(得分:12)

当发生此特定链接器错误时,通常是针对一个版本的Python构建应用程序的结果,例如Python 3.x头文件,而boost_python库是针对差异版本构建的,例如为2.x。

boost/python/module_init.hpp中,init_module函数在构建Python 3.x时具有以下签名:

PyObject* boost::python::detail::init_module(PyModuleDef&, void(*)());
构建Python 2.x时的

和以下签名:

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

implementation 可以看出,Boost.Python库中只有一个函数存在。因此,如果正在链接Boost.Python库,并且链接器只是抱怨无法解析3.x init_module函数,那么很可能是针对Boost.Python库构建的Python 2.x版本,而应用程序代码是针对Python 3.x头文件构建的。您可以通过转储Boost.Python库的符号来验证这一点,并检查init_module签名。

要解决此问题,请使用构建Boost.Python的相同版本的Python构建应用程序。在这种情况下,要么:

  • 使用Python 2.x头文件构建应用程序并链接Python 2.x库。
  • 针对Python 3.x构建Boost.Python。 This文档描述了构建Boost的步骤,并且this文档详细介绍了Boost.Python。可能有必要使用bootstrap参数显式提供Boost.Python将在--with-python进程中构建的Python可执行文件。

答案 1 :(得分:6)

您缺少Python开发标头。你的Linux发行版应该有一个包。 (例如,Debian或Ubuntu上的python-dev。)

答案 2 :(得分:2)

您正在构建共享库,因为这是二进制Python模块。为此,你需要-shared或-dynamic(检查文档),你不应该有一个main()函数。

此外,如果这没有帮助并且您仍然有链接器错误,请使用“objdump -T --demangle / path / to / lib”来查找库包含哪些符号以及它是否包含您需要的符号。还要检查“ldd”的输出,它列出了相关的共享对象。这应该会提示您链接哪个库或库。

在我的系统上,我还有一个名为“python-config”和“python2.7-config”的程序。检查你是否有类似的东西,因为这个脚本知道至少为python链接哪些库。一个类似的工具是pkg-config,它更通用,也可能为boost提供信息。

答案 3 :(得分:2)

不确定这是否可行,但似乎PY_VERSION_HEX设置错误。 如果你

会发生什么
#define PY_VERSION_HEX 0x03300000

在BoostPythonTest.cpp中包含boost.python标头之前?

答案 4 :(得分:1)

您还必须链接Boost.System以及链接器提到的任何其他库。另外,尝试其他编译器,例如Clang(https://svn.boost.org/trac/boost/ticket/7536),它带有XCode(Latest Clang location in XCode 4.5)。另外,尝试发布您的makefile。另一种尝试是使用bjam / b2而不是make。