我正在尝试找到一种使用 pybind11 构建和运行带有嵌入式 python 解释器的 cpp 文件的方法。
在本教程中,它使用 CMake,但我正在寻找一种无需 CMake 即可完成此操作的方法。
这是我尝试过的。
在示例.cpp中:
#include <pybind11/embed.h> // everything needed for embedding
namespace py = pybind11;
int main() {
py::scoped_interpreter guard{}; // start the interpreter and keep it alive
py::print("Hello, World!"); // use the Python API
}
Run Code Online (Sandbox Code Playgroud)
当我运行以下命令时,在终端中:(构建良好)
c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` example.cpp -o example
Run Code Online (Sandbox Code Playgroud)
然后运行二进制文件
./example
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
dyld:未找到符号:_PyBaseObject_Type 引用自:/Users/cuinjune/Desktop/pybindtest/./example 预期位置:/Users/cuinjune/Desktop/pybindtest/./example 中的平面命名空间 zsh:中止 ./example
有没有可能的方法可以使用 pybind11 正确构建和执行带有嵌入式 python 解释器的 cpp 文件?(不使用 CMake)
我看过很多关于解决此类链接器错误的帖子,在大多数情况下,人们只是忘记使用 进行编译-fPIC,有时人们在使用内联函数时遇到麻烦,等等,但这里的情况并非如此。我正在尝试使用Pybind11包装 python 的 c++ 库。在此过程中,我想将一些静态库(其中之一是newmat11)链接到 .so 文件中。
我使用 automake 系统构建 newmat11 库-fPIC(这是一些输出......)
...
g++ -DHAVE_CONFIG_H -I. -g -O2 -MT newmat8.lo -MD -MP -MF .deps/newmat8.Tpo -c newmat8.cpp -fPIC -DPIC -o newmat8.o
...
ar cru libnewmat11.a bandmat.o cholesky.o evalue.o fft.o jacobi.o hholder.o myexcept.o newfft.o newmat1.o newmat2.o newmat3.o newmat4.o newmat5.o newmat6.o newmat7.o newmat8.o newmat9.o newmatex.o newmatrm.o solution.o sort.o submat.o svd.o
Run Code Online (Sandbox Code Playgroud)
事实上,当我运行时readelf --relocs libnewmat11.a,我看到很多重新定位的符号。这是给我带来麻烦的一个:
$readelf --relocs libnewmat11.a | grep ZTIN6NEWMAT17Sing
000000001d20 013c00000002 R_X86_64_PC32 …Run Code Online (Sandbox Code Playgroud) 我有一个 C++ 项目,我正在为其开发 Python 接口。现在我正在使用pybind11因为它看起来很简洁,并且有一些很好的工具可以使用 CMake 构建扩展模块,这就是主要的 C++ 项目的构建方式。
通过 CMake 我设法获得了一个包含要构建的接口函数的共享库,但是现在我有了它我不知道如何告诉 Python 它存在并使其可导入。我不想重新配置要通过 Python 启动的整个项目构建(即如这里使用 setuptools 所述),因为它是一个大项目,我只是为它的一部分提供了一个 Python 接口。因此,如果我可以只为 Python 构建共享库以及其余的 C++ 代码,然后再运行“setup.py install”来执行其他任何需要使共享库可见的操作,那就更好了到 Python。
这可能吗?或者我是否需要进行一些其他类型的重构,例如让主项目构建一些其他纯 C++ 库,然后我只需将其链接到通过 setuptools 单独构建的 Python 扩展模块库?
我想用 PyBind11 绑定一个 C++ 函数。问题是这个函数有一个带双指针的参数,编译器会引发错误
error: cannot initialize a parameter of type 'char **' with an rvalue of type 'typename make_caster<char **>::cast_op_type<typename std::add_rvalue_reference<char**>::type>' (aka 'char *').
具体代码如下:
#include <pybind11/pybind11.h>
#include <iostream>
namespace py = pybind11;
void parse_args(int argn__, char** argv__)
{
for(int i = 1; i < argn__; ++i)
{
std::cout<< argv__[i];
}
}
PYBIND11_MODULE(argv_bind, m) {
m.def("parse_args", &parse_args);
}
Run Code Online (Sandbox Code Playgroud) 在Pybind11中是否可以在Python端使用mpi4py然后将通信器移交给C++端?
如果是这样,它将如何运作?
如果没有,是否可以使用Boost?如果是这样,它会怎么做?
我在网上搜索了几个小时,但没有找到任何东西.
为了更好地理解如何使用pybind库将参数从Python传递到C++函数,我想构建一个小的虚拟/演示代码,我可以在C++端接收Python列表,将其转换为浮点指针对象,以及然后打印出来.
虽然我知道我可以使用这个py::list类,但我还没有想出这个类可用的方法.我查看了文档参考,然后在代码(list.h,stl.h)中查找并且无法确定哪些方法可用.
相当于__getitem__什么?我有可用的每个python方法py::list吗?
如果我在不同的 pybind11::scoped_interpreter 会话中两次导入外部模块,应用程序将在 eval.h 中的函数 eval 中崩溃,如下行:
PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
Run Code Online (Sandbox Code Playgroud)
和
Exception thrown at 0x00007FFD710C4E0C (multiarray.cp36-win_amd64.pyd) in pybind-test.exe: 0xC0000005: Access violation writing location 0x000000000000000A.
Run Code Online (Sandbox Code Playgroud)
namespace py = pybind11;
void test() {
try {
py::scoped_interpreter guard{};
py::object mainScope = py::module::import("__main__").attr("__dict__");
py::exec(
"import numpy\n",
mainScope);
}
catch (py::error_already_set const &pythonErr) { std::cout << pythonErr.what(); }
}
int main() {
test(); // Runs fine
test(); // Crashes at py::exec
}
Run Code Online (Sandbox Code Playgroud)
我觉得这与 pybind11 的 embed.h 中的注释有关:
可以通过
initialize_interpreter再次调用来重新启动解释器。使用 …
我的项目回复了一个 SO 文件,我将通过cmake在我的项目文件夹下安装它来制作它。当我运行时它可以运行文件python setup.py install
但是我是用pip安装的,因为pip会把项目拷贝成tmpfile,安装后会被删除,SO文件也被删除。因此,当我导入我的项目时,由于找不到 SO 文件而失败。
当然,我可以将 SO 文件安装到/usr/local/lib,但我不想
任何人都有解决它的想法?
我正在 Ubuntu (20.04) 上的 VSCode (1.46.1) 中创建一个带有 CMake (3.16.3) 和 pybind11 (2.4.3) 的入门项目,默认情况下它同时具有 Python 2.7 和 3.8。我想为 Python3 构建一个模块。当我在 CMakeLists.txt 中使用以下两行时
find_package(pybind11)
find_package(Python COMPONENTS Interpreter Development REQUIRED)
Run Code Online (Sandbox Code Playgroud)
CMake 配置是
[cmake] -- Found PythonInterp: /usr/bin/python (found version "2.7.18")
[cmake] -- Found PythonLibs: /usr/lib/x86_64-linux-gnu/libpython2.7.so
[cmake] -- Found Python3: /usr/bin/python3.8 (found version "3.8.2") found components: Interpreter Development
Run Code Online (Sandbox Code Playgroud)
切换 find_package 语句的顺序
find_package(Python COMPONENTS Interpreter Development REQUIRED)
find_package(pybind11)
Run Code Online (Sandbox Code Playgroud)
提供相同的 python 链接,但使用新的顺序
[cmake] -- Found Python: /usr/bin/python3.8 (found version "3.8.2") found components: Interpreter Development
[cmake] -- …Run Code Online (Sandbox Code Playgroud)