如何将Python3嵌入标准库 [英] How to embed Python3 with the standard library
问题描述
我正在尝试将Python嵌入(最终是多平台)C ++应用程序中。
重要的是,我的应用程序必须包含自己的Python实现(与Blender一样),因此它是完全独立的。 (否则它将成为配置雷区。)
我有两个选择:
-
尝试在标准库中嵌入Python3 (我曾要求此处)
-
试图在标准库中嵌入Python3 。
(2)需要什么?
有这些信息使我能够在每种方法的优点与设置它所需的工作量之间取得平衡。
我的嵌入式Python供我自己使用(而不是任何一种)。 userland脚本)-主要控制流程/游戏逻辑。我将不需要标准库中的任何东西-也许我可以在需要时通过隧穿回C ++将其减少到0-例如,如果我需要一个随机数,则可以创建一个C ++例程并从Python访问该例程。我已经涵盖了所有内容。
但是,它似乎开始看起来即使最小的安装也必须包含一些stdlib组件,这提示了一个问题:如果我必须包含一些,也许最好将所有内容都包含在内!
由于这实际上没有答案,因此我将为您提供后人。我也无法访问Mac,因此与Linux相比,它可能对您有所不同。另外,必须安装必需的依赖项才能使此函数正常工作,但这通常很容易找出。
创建工作目录
mkdir〜/ embeddedpython
cd〜/ embeddedpython
下载Python源代码
wget https://www.python.org/ftp/python/ 3.6.1 / Python-3.6.1.tgz
为Python创建安装目录
mkdir ./安装
提取下载的源文件
tar xvf Python-3.6.1.tgz
输入新创建的源目录
cd Python-3.6.1
配置Python以在我们的安装目录中安装
./ configure --prefix = / home /<用户名> / embeddedpython / installation
制作并安装Pytho n
make&&进行安装
返回工作目录
cd ..
创建新的 PYTHONHOME 该库将驻留的目录
mkdir home&& mkdir home / lib
将Python库复制到我们的新主目录
cp -r ./installation/lib/python3.6 ./home/lib/
使用下面的代码从 Python文档,但 setenv
函数调用除外。
#include< Python.h>
#include< cstdlib>
int main(int argc,char * argv [])
{
setenv( PYTHONHOME, ./home,1);
wchar_t * program = Py_DecodeLocale(argv [0],NULL);
if(program == NULL){
fprintf(stderr,致命错误:无法解码argv [0] \n);
出口(1);
}
Py_SetProgramName(program); / *可选,但建议使用* /
Py_Initialize();
PyRun_SimpleString( from time import time,ctime\n
print(’Today is’,ctime(time()))\n);
if(Py_FinalizeEx()< 0){
exit(120);
}
PyMem_RawFree(程序);
返回0;
}
编译并运行
g ++ Embeddedpython.cpp -I ./installation/include/python3.6m/ ./installation/lib/libpython3.6m.a -lpthread -ldl -lutil
./ a.out
>今天是星期五4月14日16:06:54 2017
从这里开始,它像往常一样是标准的嵌入式python 。使用此方法,必须在部署中包括 home目录,并且必须在执行任何与python相关的代码之前将环境变量 PYTHONHOME
设置为指向该目录。 / p>
I am attempting to embed Python in an (ultimately multiplatform) C++ app.
It's important that my app contains its own Python implementation (in the same way that blender does), so that it is entirely self-contained. (Else it becomes a configuration minefield).
I have two options:
Attempt to embed Python3 without the standard library (which I have asked here)
Attempt to embed Python3 with the standard library.
What is required for (2)?
With this information I would be able to balance the merits of each approach against the effort required to set it up.
My embedded Python will be for my own use (rather than any userland scripting) -- mainly control flow / game logic. I will need very little from the standard library -- maybe I can whittle that down to 0 by tunnelling back into C++ whenever necessary -- for example if I need a random number, I can create a C++ routine and access that from Python. I have all of that covered.
However, it is starting to look as though even a minimal installation will have to contain some stdlib component(s), which prompts the question: "If I must include some, maybe it is better to include all!"
Since this doesn't really have an answer, I will offer this for posterity. I also do not have access to a Mac, so it may be a little different for you than on Linux. Also, the required dependencies must be installed for this to work, but that is usually easy enough to figure out.
Create a working directory
mkdir ~/embeddedpython
cd ~/embeddedpython
Download the Python source
wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz
Create an installation directory for Python
mkdir ./installation
Extract the downloaded source files
tar xvf Python-3.6.1.tgz
Enter the newly created source directory
cd Python-3.6.1
Configure Python to install in our installation directory
./configure --prefix="/home/<username>/embeddedpython/installation"
Make and install Python
make && make install
Go back to your working directory
cd ..
Create a new PYTHONHOME directory where the library will reside
mkdir home && mkdir home/lib
Copy the Python library to our new home directory
cp -r ./installation/lib/python3.6 ./home/lib/
Create a new c++ source file (embeddedpython.cpp) with the following code taken from the python documentation, with the exception of the setenv
function call.
#include <Python.h>
#include <cstdlib>
int main(int argc, char *argv[])
{
setenv("PYTHONHOME", "./home", 1);
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");
if (Py_FinalizeEx() < 0) {
exit(120);
}
PyMem_RawFree(program);
return 0;
}
Compile and run
g++ embeddedpython.cpp -I ./installation/include/python3.6m/ ./installation/lib/libpython3.6m.a -lpthread -ldl -lutil
./a.out
> Today is Fri Apr 14 16:06:54 2017
From here on it is standard embedded python as usual. With this method, the "home" directory must be included in your deployment, and the environment variable PYTHONHOME
must be set to point to it before any python related code is executed.
这篇关于如何将Python3嵌入标准库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!