简体   繁体   English

将Python嵌入C ++

[英]Embedding Python into C++

If this question could be worded better/needs to be split into many questions, please alert me 如果可以更好地表达这个问题/需要分为多个问题,请提醒我

I need to package Python scripts in order to ship them as single-executables (ideally), or single-executables with supporting files (non-ideally). 我需要打包Python脚本,以便将它们作为单个可执行文件(理想情况下)或具有支持文件的单个可执行文件(非理想情况下)进行运输。

I have seen py2app and py2exe. 我看过py2app和py2exe。 They do not fit my requirements, as I am looking for a single method to do this, and in the future may need to have the packaged scripts interact with the executable that they are being run from. 它们不符合我的要求,因为我正在寻找一种方法来执行此操作,并且将来可能需要使打包的脚本与从其运行的可执行文件进行交互。

What is the best way to go about this? 最好的方法是什么? The scripts which I would be embedding may even require multiple files, which complicates matters I'm sure. 我要嵌入的脚本甚至可能需要多个文件,这使我确定的事情变得复杂。

If I wanted to use an interpreter other than CPython (ie: PyPy or Stackless) in the future, would the process be different (other than API calls in the C++ executable)? 如果将来我想使用除CPython之外的其他解释器(即:PyPy或Stackless),该过程是否会有所不同(除了C ++可执行文件中的API调用之外)?

Does Python have to be installed on the computers which would be running the package, or does embedding Python mean that it is fully embedded? 是必须在运行该软件包的计算机上安装Python,还是嵌入 Python意味着它已完全嵌入? I saw on the Python Wiki something about Py_SetPythonHome() , which would indicate to me that it needs Python (or at least its libraries) to be installed. 我在Python Wiki上看到了有关Py_SetPythonHome() ,这向我表明它需要安装Python(或至少它的库)。 Am I correct? 我对么?

PyInstaller with the --onefile option will put everything inside a single file, though it will take a little more time to startup. PyInstaller--onefile选项将会把所有的单个文件中,虽然这将需要多一点时间来启动。 I'm afraid it's not compatible with PyPy, but it should not be so tricky to get it working using Stackless. 恐怕它与PyPy不兼容,但是使用Stackless使它工作起来并不那么棘手。

Good luck! 祝好运!

Are you sure that you need to embed the Python files? 您确定需要嵌入Python文件吗?

I ask because you mention you want to package the Python files as single executables. 我问是因为您提到要将Python文件打包为单个可执行文件。 Couldn't you install Python on the target machine and since Python scripts are executables on their own, you would only need something to kick them off. 您无法在目标计算机上安装Python,并且由于Python脚本本身就是可执行文件,因此您只需要启动它们即可。 A master python script could kick off all the rest of the scripts. 一个主python脚本可以启动所有其他脚本。

Otherwise you should look in C++ what can run a Python script. 否则,您应该在C ++中查看可以运行Python脚本的内容。 Then have the master python script run all the other scripts. 然后让主python脚本运行所有其他脚本。

Yes you can! 是的你可以!

The easiest is with newest Python3 <OS> <arch> embeddable zip file , which contains .so/.dll and all modules. 最简单的方法是使用最新的Python3 <OS> <arch> embeddable zip file ,其中包含.so / .dll和所有模块。

Instructions are here: https://docs.python.org/3/extending/embedding.html 说明在这里: https : //docs.python.org/3/extending/embedding.html

#include <Python.h>

int
main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");
    Py_Finalize();
    PyMem_RawFree(program);
    return 0;
}

The trickier part is communication between your C++ code and Python code. 棘手的部分是C ++代码和Python代码之间的通信。

If you only have to pass a few strings back and forth, that's trivial, but if you want a very tight integration, then you'll probably need a few of these: 如果只需要来回传递一些字符串,这是微不足道的,但是如果您想要非常紧密的集成,则可能需要其中一些:

  • create a Python module in (C++ code, C ABI) and inject it -- that means Python will be able to run import yourmod; yourmod.yourfunc(...) 在(C ++代码,C ABI)中创建一个Python模块并将其注入-这意味着Python将能够运行import yourmod; yourmod.yourfunc(...) import yourmod; yourmod.yourfunc(...) which will run your C++ custom code and/or import yourmod; yourmod.yourfunc(...)将运行您的C ++自定义代码和/或
  • resolve and call Python functions from C++ (the inverse) https://stackoverflow.com/a/3310608/705086 从C ++解析并调用Python函数(反之) https://stackoverflow.com/a/3310608/705086

Single executable 单个可执行文件

If you cannot have an installer, and really do not wish to have a bunch of .DLL/.so/etc it's described eg here Merge DLL into EXE? 如果您没有安装程序,并且真的不希望拥有一堆.DLL / .so / etc,例如此处所述,将DLL合并到EXE? and it's ABI-specific, there will be one way for Windows, another Linux, etc, and you may have to override Python's import machinery (so that it doesn't look for dll/so in the file system) -- at this point, you may as well use PyInstaller or extend/merge PyInstaller with your application. 而且它是针对ABI的,有一种方法可以用于Windows,另一种Linux等,并且您可能必须覆盖Python的导入机制(这样它就不会在文件系统中查找dll / so)。 ,您也可以在应用程序中使用PyInstaller或扩展/合并PyInstaller。 Please research https://github.com/pyinstaller/pyinstaller/tree/develop/bootloader/src and evaluate how hard that might be 请研究https://github.com/pyinstaller/pyinstaller/tree/develop/bootloader/src并评估其难度

PyPy PyPy

Simple embedding is possisble http://doc.pypy.org/en/latest/embedding.html but single-file embedding is not. 简单的嵌入是可能的http://doc.pypy.org/en/latest/embedding.html,但单文件嵌入不是。 You could hack PyPy source and build custom embeddable object, but you'd be the first to do so :) 您可以破解PyPy源代码并构建自定义可嵌入对象,但您将是第一个这样做的人:)

Stackless 无堆栈

Should be as simple as regular CPythion 应该像常规CPythion一样简单

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM