thc*_*ark 4 c++ python boost boost-python python-3.x
我不会将此添加为答案,因为我仍然没有从技术上解决问题。但由于我现在花了 2.5 天尝试让 boost-python3 工作起来,我已经失去了忍受它的意愿。
我刚刚遇到了pybind11(我之前对 python 绑定工具的长时间搜索没有找到它,我不知道)并且正在使用它。2.5 天的痛苦与安装和构建cmake 示例的不到 20 分钟相比......并且所有特定的 python 版本依赖性地狱都消失了。
它在语法上与 boost-python 类似,但更易于管理、速度更快、仅包含标头并且功能更丰富。
耶!
我正在使用 boost::python 绑定 python 3.7.2 中的类。
类导入成功,但实例化它会出现以下错误:
<my-terminal>$ python
Python 3.7.2 (default, Feb 14 2019, 17:36:47)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import classes
>>> t = classes.World()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'NoneType'
>>>
Run Code Online (Sandbox Code Playgroud)
这是classes.cpp:
#include <boost/python.hpp>
#include <boost/python/list.hpp>
#include <boost/python/extract.hpp>
#include <string>
#include <sstream>
#include <vector>
struct World
{
void set(std::string msg) { mMsg = msg; }
void many(boost::python::list msgs) {
long l = len(msgs);
std::stringstream ss;
for (long i = 0; i<l; ++i) {
if (i>0) ss << ", ";
std::string s = boost::python::extract<std::string>(msgs[i]);
ss << s;
}
mMsg = ss.str();
}
std::string greet() { return mMsg; }
std::string mMsg;
};
using namespace boost::python;
BOOST_PYTHON_MODULE(classes)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
.def("many", &World::many)
;
};
Run Code Online (Sandbox Code Playgroud)
由于 python 2/3 问题(链接到 python 3 而不是 python 2 库),这个问题几乎相同地得到了解决。所以我怀疑是库链接问题。
我无法让 bjam 工作,并且无论如何也无法将我们的所有构建系统切换为一个模块...所以我使用 cmake 进行构建,它成功编译为classes.so输出如下,表明我找到了所有正确的包含、库和可执行文件:
-- Found PythonInterp: /Users/me/.pyenv/versions/boost37/bin/python3 (found suitable version "3.7.2", minimum required is "3")
PYTHON_VERSION_SUFFIX
-- Boost version: 1.68.0
-- Found the following Boost libraries:
-- python37
-- Found PythonLibs: /usr/local/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib (found suitable version "3.7.2", minimum required is "3")
-- PYTHON_LIBRARIES = /usr/local/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib
-- PYTHON_EXECUTABLE = /Users/thc29/.pyenv/versions/boost37/bin/python3
-- PYTHON_INCLUDE_DIRS = /usr/local/Frameworks/Python.framework/Versions/3.7/include/python3.7m
-- Boost_LIBRARIES = /usr/local/lib/libboost_python37-mt.dylib
Run Code Online (Sandbox Code Playgroud)
Boost-python3库目录内容:
ls /usr/local/Cellar/boost-python3/1.68.0/lib
libboost_numpy37-mt.a libboost_numpy37.dylib libboost_python37.a
libboost_numpy37-mt.dylib libboost_python37-mt.a libboost_python37.dylib
libboost_numpy37.a libboost_python37-mt.dylib
Run Code Online (Sandbox Code Playgroud)
我使用了brew install boost,并brew install boost-python3 --build-from-source激活了 python 3.7 virtualenv,以确保 boost-python3 链接到正确的 python 版本。
正在检查库...
otool -L classes.so给出:
classes.so:
/usr/l/opt/boost-python3/lib/libboost_python37-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python (compatibility version 3.7.0, current version 3.7.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
Run Code Online (Sandbox Code Playgroud)
otool -L /usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib给出:
/usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib:
/usr/local/opt/boost-python3/lib/libboost_python37-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
Run Code Online (Sandbox Code Playgroud)
在相关问题中,这表明了他们的问题。但这里看起来很好!
经过正确编译并检查链接的痛苦过程后,我找不到任何缺陷。这是一个不同的问题吗?或者是否存在我没有发现的链接问题?
谢谢你的帮助!
为使用 Anaconda 或 Conda-Forge 发行版的用户添加答案:
python 解释器在libpythonXY库中静态链接。这就是为什么它使 python 二进制文件与其他发行版不同。
OP 报告的问题的修复方法是使用:
-undefined dynamic_lookup
Run Code Online (Sandbox Code Playgroud)
代替:
-lpythonXY
Run Code Online (Sandbox Code Playgroud)
您正在创建 Python C/C++ 扩展,而不是嵌入 python 解释器。所以你不应该链接到 python 库。Pybind11 可以正确处理这个问题。
请参阅以下内容了解更多信息:
顺便说一句,python 3.8 添加了一个附加标志:--embed并且只有这样它才会-lpythonXY在输出中添加:
$ python3.8-config --libs
-ldl -framework CoreFoundation
$ python3.8-config --libs --embed
-lpython3.8 -ldl -framework CoreFoundation
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
985 次 |
| 最近记录: |