【发布时间】: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);
}
makefile:
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