用C++应用程序封装Python,该应用程序使用pybind11嵌入Python



我有一个C++应用程序,我正在尝试使用pybind11来支持我的应用程序中的脚本系统,该系统允许用户编写自己的脚本。我正在尝试使用Python,就像许多人使用Lua作为脚本语言来扩展应用程序的功能一样。

我发现Lua与Python/pybind11有一个很大的区别:使用Lua,我可以静态地将脚本语言链接到我的可执行文件中,甚至可以打包一个共享库,但使用Python/pybind11,我似乎依赖于最终用户的系统上是否已经安装了Python。

这是正确的吗?

有没有一种方法可以告诉pybind11静态链接Python库?

pybind11似乎也会搜索python可执行文件的路径,然后假设共享库在同一个文件夹中。有没有一种方法可以分发共享库,然后告诉我的嵌入式解释器使用那些共享库?

我的最终目标是,用户可以在他们的机器上安装我的C++应用程序,我的应用程序将有一个内置的Python解释器,可以执行脚本,无论机器上是否真的安装了Python。理想情况下,我会使用静态链接来实现这一点,但动态链接和分发所需的库也是可以接受的。

  1. Pybind11不搜索Python可执行文件或类似内容。您可以链接到libpythonX.Y.so.Z,它的工作原理与任何其他共享库一样。因此,您可以链接到您分发的Python库。你只需要确保你的可执行文件在运行时能找到你的库。同样,这与分发任何其他共享库没有什么不同。使用rpath,或者在包装脚本中使用LD_LIBRARY_PATH,或者其他什么。在SO(第一次点击)上有很多关于它的问题和答案。

  2. 如果有可用的静态Python库,则可以链接该库。在我的系统(Ubuntu 20 x64)上,试图链接libpython3.8.a会产生大量的重新定位错误。只有当整个可执行文件都是静态构建的,即使用g++ -static ...时,系统库才能工作。如果您需要动态可执行文件,则需要使用-fPIC构建自己的静态Python库。这里是我用来链接到系统库的命令。

    g++ -static -pthread -I/usr/include/python3.8 example.cpp -lpython3.8 --ldl -lutil -lexpat -lz
    
  3. 最后但同样重要的是,如果您的用户想要编写Python脚本,他们可能安装了Python。

最新更新