【问题标题】:Boost.Python and C++ compiled library error while importing to Python 3导入 Python 3 时 Boost.Python 和 C++ 编译库错误
【发布时间】:2018-11-24 01:50:55
【问题描述】:

在 Python 3 中,我尝试导入用 C++ 编译的共享库。目前,我在 CentOS 7 上安装了这些软件包:

  • g++ --version -> g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)
  • conda list anaconda$ -> Anaconda 3 版本 5.2.0 与构建通道 py36_3

使用 Boost.Python 将 C++ 中的一个简单文件 greet.cpp 编译为共享库 greet.so。我在 youtube Simple Demo of Boost Python of Python calling C++ library 上观看了一段视频,但由于某些原因未能找到 Python.h。我不得不在makefile 中更改了一些内容,最终我编译所有内容都没有错误。但是,当我尝试在 Python 解释器中将共享库 pygreet.so 作为模块导入:import pygreet 时,出现此错误:

ImportError: /home/.../cpp/code/pygreet.so: undefined symbol: _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE

我试图看看这是什么东西:nm pygreet.so | less -p "_ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE" 并找到了这些行:

0000000000008916 W _ZN5boost6python3da simpleefIPFSsvEEEvPKcT_
                 U _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE

我是使用共享库的初学者,我真的不知道如何继续。下面,我将显示这些文件,以防有人看到我遗漏了一些重要的东西。

谢谢。


greet.cpp

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


namespace py = boost::python;


std::string greet() {
    return "hello, world";
}


int square(int number) {
    return number * number;
}


BOOST_PYTHON_MODULE(pygreet)
{
    // Add regular functions to the module.
    py::def("greet", greet);
    py::def("square", square);
}

ma​​kefile

CXX = g++
PYLIBPATH = $(shell python3-config --exec-prefix)/lib
LDFLAGS = -L$(PYLIBPATH)
LFLAGS = $(shell python3-config --libs) -lboost_python
CFLAGS = -Wall -Werror
INCLUDES = $(shell python3-config --includes)

SOURCE = greet.cpp
TARGET = pygreet.so
OBJ = $(SOURCE:.cpp=.o)

default: $(TARGET)
    @echo $(TARGET) compiled!

$(TARGET): $(OBJ)
    $(CXX) $(CFLAGS) $(LDFLAGS) $(LFLAGS) -Wl,-rpath,$(PYLIBPATH) -shared $< -o $@

greet.o: $(SOURCE)
    $(CXX) $(CFLAGS) $(INCLUDES) -fpic -c $< -o $@

clean:
    rm -rf *.so *.o

.PHONY: deafult clean

编辑。

按照评论中的建议,我更改了makefile 中的行:

PYLIBPATH = $(shell python3-config --exec-prefix)/lib
LDFLAGS = -L$(PYLIBPATH)
LFLAGS = $(shell python3-config --libs) -lboost_python

PYLIBPATH = $(shell python3-config --exec-prefix)
LDFLAGS = $(shell python3-config --ldflags) -lboost_python

然后

$(CXX) $(CFLAGS) $(LDFLAGS) $(LFLAGS) -Wl,-rpath,$(PYLIBPATH) -shared $< -o $@

$(CXX) $(CFLAGS) $(LDFLAGS) -Wl,-rpath,$(LDFLAGS) -shared $< -o $@

但仍然有同样的错误。

【问题讨论】:

  • 为什么不使用python3-config --ldflags 来获取链接所需的所有标志库?
  • 啊。我关注了我提供链接的视频,但没有意识到我可以检查--help。然后,我会知道的。感谢您指出了这一点。我会检查它是否运行正常
  • 只有一个问题。你认为我应该为-rpath 提供什么? python3-config --ldflags返回的整个字符串?
  • 如果需要一个rpath,它应该包含在--ldflags提供的标志中。
  • 那里没有提供。无论我在编译共享文件时使用什么,我都会遇到同样的错误。

标签: c++ python-3.x boost-python


【解决方案1】:

Boost 为 Python 2 和 Python 3 提供了单独的库。如果您使用的是 Python 3,则需要链接到 Python 3 特定的库,否则在模块加载时会出现未定义符号错误。

在 Ubuntu 上,该库可能称为 libboost_python-py35.so。我很确定(但没有验证)boost.python 库的不同次要版本是向上兼容的,所以你可以在 Python 3.6 中使用libboost_python-py35.so

如果你的系统上没有这样的库,很可能你的发行版没有提供它,在这种情况下你需要从源代码构建 boost.python。

【讨论】:

  • 我明白了。我已经从包管理器 (yum install boost-devel) 安装了 boost,结果发现 Centos7 中可用的 boost 仅适用于 Python2:/。伟大的。感谢您澄清这一点。至少我知道问题出在哪里。
  • @Celdor 可能有单独的包 boost-python3-devel,看看吧。
  • sudo yum list available | grep "boost".*"devel" 显示:boost-devel.i686 1.53.0-27.el7 base。我猜 27 指的是 Python2.7。没有什么比这更多了。正如所指出的,我可能必须从源代码编译提升。
猜你喜欢
  • 2020-02-17
  • 2013-03-13
  • 1970-01-01
  • 2018-03-17
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多