在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);
}
生成文件:
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 $@
但仍然有同样的错误。
答案 0 :(得分:1)
Boost为Python 2和Python 3提供单独的库。如果您使用的是Python 3,则需要链接Python 3特定的库,否则在模块加载时会出现未定义的符号错误。
在Ubuntu上,可以将库称为libboost_python-py35.so
。我很确定(但没有验证)boost.python库的不同次要版本是向上兼容的,因此您可以将libboost_python-py35.so
与Python 3.6一起使用。
如果你的系统上没有这样的库,很可能你的发行版没有发布它,在这种情况下你需要从源代码构建boost.python。