如何使用嵌入式Python解释器(pybind11)编译和执行cpp文件

4
我正在尝试使用pybind11构建和运行一个包含Python解释器的cpp文件。 根据这个教程,它使用CMake,但我正在寻找一种无需使用CMake实现此目的的方法。 以下是我的尝试: 在example.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
}

在终端中运行以下命令:(成功构建)
c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` example.cpp -o example

然后使用以下命令运行二进制文件:

./example

我遇到了以下错误:
dyld:找不到符号:_PyBaseObject_Type 参考自: /Users/cuinjune/Desktop/pybindtest/./example 应在 /Users/cuinjune/Desktop/pybindtest/./example 的平面命名空间中 预期在zsh中中断的。/example 是否有可能使用pybind11嵌入Python解释器来正确构建和执行cpp文件?(而无需使用CMake)
1个回答

5
通过与Python库链接,可以定义该符号(以及您需要的其他符号)。
假设已进行标准安装,则只需添加以下内容即可:
`-lpython`

如果您的系统上安装了多个Python库,则可以将其更改为CLI(或-lpython3等)。您也可以选择添加:

`python3-config --libs`

如果你的Python3已安装python3-config

编辑: 根据评论,你的设置中链接器无法访问相关的库目录。一种选择是使用完整的标志集:

`python3-config --ldflags`

我仍然假设python3-config与您的python3匹配。如果不是这样,另一种选择是获取distutils目录。在其前面添加-L并根据您的安装情况添加-lpython-lpython3

-L`python3 -c 'import distutils.sysconfig as ds; print(ds.get_config_var("LIBDIR"))'` -lpython

(是的,还有一个“LDFLAGS”config_var,但那些是用于构建Python的标志,不太可能是你想要的。)

我尝试了以下命令:c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup python3-config --libs -lpython python3 -m pybind11 --includes example.cpp -o example,但是我遇到了ld: library not found for -lpython3.7m的错误。我也尝试了-lpython3.7m,但是出现了相同的错误。 - Zack Lee
当我尝试运行 c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup -lpython python3 -m pybind11 --includes example.cpp -o example 时,它可以成功构建,但是当我运行二进制文件时,会出现“dyld: Symbol not found: _PyInstanceMethod_Type”的错误提示。 - Zack Lee
1
我更新了答案。前者是正确的选择;后者很可能会选择一个Python2库(因为PyInstanceMethod_Type存在于3中,而不是2中)。 - Wim Lavrijsen
c++ -O3 -Wall -std=c++11 -undefined dynamic_lookup python3-config --ldflags python3 -m pybind11 --includes example.cpp -o example 已经成功运行。非常感谢! - Zack Lee
1
我不熟悉Xcode,如果它直接支持Python也不会让我感到惊讶,因为其他IDE也是这样。但是在编辑链接器标志时,您可能需要直接输入完整的标志(python3-config是一个程序,因此除非Xcode在shell上编译,否则不会运行)。通过在shell上运行python3-config --ldflags来获取标志,然后将结果复制到“其他链接器标志”中。由于您不会分发Xcode构建环境,因此硬编码输出不应该是实际问题。 - Wim Lavrijsen
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接