boost_python 导入错误:模块未定义 init 函数
首先:我查看了相关问题,但不幸的是它们并不是很有帮助。我正在尝试包装外部库中的枚举和类。
#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;
#include <libvpsc/rectangle.h>
using vpsc::Rectangle;
using vpsc::Dim;
BOOST_PYTHON_MODULE(adaptagrams)
{
enum_<Dim>("dim")
.value("x", vpsc::XDIM)
.value("y", vpsc::YDIM)
.value("unset", vpsc::UNSET)
;
class_<Rectangle>("Rectangle",
init<double, double, double, double, optional<bool> >())
.add_property("centerX", &Rectangle::getCentreX)
.add_property("centerY", &Rectangle::getCentreY)
.add_property("width", &Rectangle::width, &Rectangle::set_width)
.add_property("height", &Rectangle::height, &Rectangle::set_height)
;
}
并编译:
g++ -fPIC -I/usr/include/python2.7 -c adaptagrams.cpp -o adaptagrams.o
g++ -shared -Wl,-soname,adaptagrams.so -o adaptagrams.so adaptagrams.o -lpython2.7 -lboost_python -lvpsc
但是,当我尝试导入 .so 模块时,出现错误:
ImportError: dynamic module does not define init function (PyInit_adaptagrams)
有什么想法吗?
更新:当我重新启动Python并尝试导入时,得到的第一个错误是:
ImportError: ./adaptagrams.so: undefined symbol: _ZN8topology13computeStressERKSt6vectorIPNS_4EdgeESaIS2_EE
当我再次尝试时,第二个错误是上面的动态导入(2.7)和段错误(3.2)。 Boost 是针对 2.7 和 3.2 编译的,我在每种方法上都链接了正确的方法。
更新 2: boost_python 页面中的教程代码有效:
#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;
struct Hello
{
Hello(std::string msg): msg(msg) {}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(constructor)
{
class_<Hello>("Hello", init<std::string>())
.def("greet", &Hello::greet)
.def("set", &Hello::set)
;
}
相同的编译:
g++ -fPIC -I/usr/include/python2.7 -c constructor.cpp -o constructor.o
g++ -shared -Wl,-soname,constructor.so -o constructor.so constructor.o -lpython2.7 -lboost_python
First off: I looked at the related questions, but they are not very helpful unfortunately. I'm trying to wrap an enum and a class from an external library.
#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;
#include <libvpsc/rectangle.h>
using vpsc::Rectangle;
using vpsc::Dim;
BOOST_PYTHON_MODULE(adaptagrams)
{
enum_<Dim>("dim")
.value("x", vpsc::XDIM)
.value("y", vpsc::YDIM)
.value("unset", vpsc::UNSET)
;
class_<Rectangle>("Rectangle",
init<double, double, double, double, optional<bool> >())
.add_property("centerX", &Rectangle::getCentreX)
.add_property("centerY", &Rectangle::getCentreY)
.add_property("width", &Rectangle::width, &Rectangle::set_width)
.add_property("height", &Rectangle::height, &Rectangle::set_height)
;
}
and compile with:
g++ -fPIC -I/usr/include/python2.7 -c adaptagrams.cpp -o adaptagrams.o
g++ -shared -Wl,-soname,adaptagrams.so -o adaptagrams.so adaptagrams.o -lpython2.7 -lboost_python -lvpsc
However, when I try to import the .so module, I get an error:
ImportError: dynamic module does not define init function (PyInit_adaptagrams)
Any ideas?
Update: When I restart Python and try the import, the first error I get is:
ImportError: ./adaptagrams.so: undefined symbol: _ZN8topology13computeStressERKSt6vectorIPNS_4EdgeESaIS2_EE
When I try it again, the 2nd one is the dynamic import from above (2.7) and a segfault (3.2). Boost is compiled against both 2.7 and 3.2 and I am linking the right ones on each approach.
Update 2: The tutorial code from the boost_python page works:
#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;
struct Hello
{
Hello(std::string msg): msg(msg) {}
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(constructor)
{
class_<Hello>("Hello", init<std::string>())
.def("greet", &Hello::greet)
.def("set", &Hello::set)
;
}
Same compilation:
g++ -fPIC -I/usr/include/python2.7 -c constructor.cpp -o constructor.o
g++ -shared -Wl,-soname,constructor.so -o constructor.so constructor.o -lpython2.7 -lboost_python
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
BOOST_PYTHON_MODULE
中使用的名称必须与您生成并导入到 python 中的.so
库的名称相匹配。The name used in
BOOST_PYTHON_MODULE
must match the name of the.so
library you generate and import into python.我以前见过这个异常。我在 Windows 上使用 Visual Studio 得到它,所以在 unix-oid 领域情况可能有点不同,但是:
两种可能性:
调试/发布不匹配:
您正在尝试将模块的调试版本导入到 python 的发布版本中(反之亦然)。解决方案是包含
boost/python/detail/wrap_python.hpp
而不是Python.h
。这将修复一些包含和定义,以便可以执行您想要的操作。Python/Boost.Python 版本不匹配:
Boost.Python 是针对一种特定版本的 python 编译的。您正在使用不同的版本。例如:您似乎使用的是 python 2.7。您的 boost_python 库可能是针对 python 2.6 编译的。是的,这意味着你的模块一次只能使用一个版本的 python。
I have seen this exception before. I got it using Visual Studio on windows, so things might be a little different over in unix-oid land but:
Two Possibilities:
Debug/Release miss-match:
You are trying to import a debug build of your module into a release build of python (or vice-versa). The solution is to include
boost/python/detail/wrap_python.hpp
instead ofPython.h
. This will fix some includes and defines to make it possible to do what you want.Python/Boost.Python version miss-match:
Boost.Python is compiled against one specific version of python. You are using it with a different version. For example: you seem to be using python 2.7. Your boost_python library might be compiled against python 2.6. Yes, this means that your module can only work with one version of python at a time.
除了其他答案(以防另一个不幸的人遇到这个问题),请确保您没有意外地使用
-fvisibility=hidden
标志进行编译。这样做似乎从 g++ / clang++ 的二进制文件中剥离了 init 函数。
背景信息
就我而言,我在将一些用 Boost.Python 制作的包装器集成到项目中时遇到了一些麻烦。当使用项目的构建系统构建时,我会得到与 OP 相同的运行时错误(而不是使用我的概念验证
Makefile
构建它,它工作得很好)。将符号表与 nm -g foo.so | 进行比较grep Py 向我展示,在非工作情况下,
PyInit_*
函数完全不存在。对编译标志进行一些比较后,我发现 -fvisibilty=hidden 是罪魁祸首。In addition to the other answers (in case another unfortunate soul runs unto this), make sure you're not accidentally compiling with the
-fvisibility=hidden
flag.Doing so seems to strip the init function from the binary in both g++ / clang++.
Background info
In my case I had some trouble integrating some wrappers made with Boost.Python into a project. When built with the project's build-system I'd get the same runtime-error as OP (as opposed to building it with my proof-of-concept
Makefile
where it worked just fine).Comparing the symbol tables with
nm -g foo.so | grep Py
showed me that in the non-working case thePyInit_*
function was completely absent. Doing some comparison between compilation flags led me to-fvisibilty=hidden
being the culprit.