我是python嵌入的新手.我试图在C++回调函数中嵌入python + numpy代码(在dll中)
我面临的问题如下.如果我有:
Py_Initialize();
// some python glue
// python invocation
Py_Finalize();
Run Code Online (Sandbox Code Playgroud)
一切正常.
但如果我有:
Py_Initialize();
_import_array(); //to initialize numpy C-API
// some python glue + numpy array object creation
// python invocation via PyObject_CallObject()
Py_Finalize();
Run Code Online (Sandbox Code Playgroud)
第二次它到达_import_array()时崩溃; (意思是它适用于第一次回调)
如果我改为执行python和numpy初始化只需一次并在析构函数中完成(因此不是每次初始化/最终化),一切都会在离开回调时崩溃.
我猜这里的问题是numpy,但我不知道如何解决它
我正在开发一个简单的(?)嵌入式 Python 项目。我有一个自定义包,已使用“setup.py install”安装到站点包中,例如:
在 C:\Python27\Lib\site-packages\ 中:
mypackage\
__init__.py
subpackage\
__init__.py
subpackage.py
....
mymodule.py
Run Code Online (Sandbox Code Playgroud)
只是做了一些简单的嵌入调用,我得到的一些行为与运行 Python 的 cmd 窗口中得到的行为不匹配。具体来说:
PyRun_SimpleString("import mypackage") //Success (return == 0)
PyRun_SimpleString("from mypackage import subpackage") //Success
PyRun_SimpleString("from mypackage import mymodule") //Fail (return == -1)
Run Code Online (Sandbox Code Playgroud)
...而所有这些在 cmd 窗口中都工作得很好(没有 ImportError,并且我可以在例如上获得预期结果dir(mymodule)
我知道结果的解释器与Py_Initialize()您在 cmd 窗口中得到的解释器有点不同,特别是 sys.path...阅读了一些其他答案后,我尝试插入 '' 作为 sys 的第一个元素.path:
PyRun_SimpleString("import sys\nsys.path.insert(0,'')")在导入失败之前,但运气不好,仍然返回-1。还尝试附加 sys.path 与 'C:\Python27\Lib\site-packages\mypackage' ,但仍然没有成功导入 'mymodule' (mymodule.py)。
基于SO和其他网站上的其他示例,我尝试了一些导入变体,例如
__import__('mypackage',globals(), locals(), fromlist=['mymodule'])
__import__('mypackage.mymodule',globals(), locals(), fromlist=['mymodule'])
Run Code Online (Sandbox Code Playgroud)
也尝试过PyImport_ImportModuleEx,与 PyRun_SimpleString 一样,它适用于除“from mypackage import mymodule”之外的所有内容。
此外:这个场景在 MacOS/Python 2.7 …
对于一个项目,我正在研究一个简单的谐波运动模拟器(质量如何随时间振荡).我已经正确生成了数据并且已经在tkinter框架工作中生成了图形.目前它只显示一个静态图形,其中我的目标是随着时间的推移将图形显示为动画.
所以为了方便起见,我使用以下代码创建了一个模拟程序:
#---------Imports
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import tkinter as Tk
from tkinter import ttk
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#---------End of imports
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01) # x-array
line, = ax.plot(x, np.sin(x))
def animate(i):
line.set_ydata(np.sin(x+i/10.0)) # update the data
return line,
ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), interval=25, blit=False)
#plt.show() #What I want the object in tkinter …Run Code Online (Sandbox Code Playgroud) 使用下一行
pModule = PyImport_Import(pName);
仅从当前目录加载模块.
但我想从其他地方加载什么?这样做有一个简洁的方法吗?
PyRun_SimpleString("import sys\nsys.path.append('<dir>')");
工作,但它有点难看 - 我正在寻找一个更好的方法
谢谢!
我试图将python程序嵌入C程序中。我的操作系统是Ubuntu 14.04
我尝试将python 2.7和python 3.4解释器嵌入到同一C代码库中(作为单独的应用程序)。嵌入python 2.7时,编译和链接有效,但不嵌入python 3.4。在链接器阶段失败。
这是我的C代码(只是一个示例,不是真实代码)
简单的
#include <stdio.h>
#include <Python.h>
int main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pFunc, *pValue;
char module[] = "get_version";
char func[] = "get_version";
char module_path[] = ".";
Py_Initialize();
PyObject *sys_path = PySys_GetObject("path");
PyList_Append(sys_path, PyUnicode_FromString(module_path));
pName = PyUnicode_FromString(module);
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule != NULL)
{
pFunc = PyObject_GetAttrString(pModule, func);
if (pFunc && PyCallable_Check(pFunc))
{
pValue = PyObject_CallObject(pFunc, NULL);
if (pValue != NULL) {
printf("Python version: %s\n", PyString_AsString(pValue));
Py_DECREF(pValue);
}
else { …Run Code Online (Sandbox Code Playgroud) 我在我的C++程序中嵌入了python.
我使用PyImport_ImportModule来加载我在.py文件中编写的模块.但是如何从内存中加载它?假设我的.py文件是加密的,所以我需要先解密它并将代码提供给python来执行.
此外,如果我可以绕过/拦截或修改导入机制,那将是很好的,因此不会从文件系统加载模块,而是我自己的内存块,我该怎么做?
ydl = youtube_dl.YoutubeDL()
with ydl:
r = ydl.extract_info("myplaylist", download=False) # don't download, much faster
print(r['uploader'],r['title'],r['thumbnail'])
Run Code Online (Sandbox Code Playgroud)
代码输出是这样的
[youtube:playlist] Downloading playlist playlistidhere - add --no-playlist to just download video videoid
[youtube:playlist] playlistidhere: Downloading webpage
[download] Downloading playlist: playlistnamehere
[youtube:playlist] playlist Spotlight On: June Recap: Downloading 39 videos
[download] Downloading video 1 of 39
[youtube] video_id: Downloading webpage
[youtube] video_id: Downloading video info webpage
[youtube] video_id: Extracting video information
[download] Downloading video 2 of 39
[youtube] video_id2: Downloading webpage
[youtube] video_id2: Downloading video …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中嵌入了 Python 3.6,我想在脚本中禁用导入命令以防止用户导入任何 Python 内置库。我只想使用语言本身和我自己的 C++ 定义的模块。
Py_SetProgramName (L"Example");
Py_Initialize ();
PyObject* mainModule = PyImport_AddModule ("__main__");
PyObject* globals = PyModule_GetDict (mainModule);
// This should work
std::string script1 = "print ('example')";
PyRun_String (script1.c_str (), Py_file_input, globals, nullptr);
// This should not work
std::string script2 = "import random\n"
"print (random.randint (1, 10))\n";
PyRun_String (script2.c_str (), Py_file_input, globals, nullptr);
Py_Finalize ();
Run Code Online (Sandbox Code Playgroud)
你知道有什么方法可以实现这一目标吗?
Python 的弃用PyEval_ReleaseLock在我们的代码库中引入了一个问题:我们希望使用 C 回调函数终止 Python 解释器Py_EndInterpreter
所以要做到这一点,Python 的 Docs说在调用这个函数时你必须持有 GIL:
void Py_EndInterpreter(PyThreadState *tstate)
销毁由给定线程状态表示的(子)解释器。给定的线程状态必须是当前线程状态。请参阅下面对线程状态的讨论。当调用返回时,当前线程状态为 NULL。与此解释器关联的所有线程状态都将被销毁。(全局解释器锁必须在调用这个函数之前被持有,并且在它返回时仍然被持有。) Py_FinalizeEx() 将销毁所有当时没有被显式销毁的子解释器。
伟大的!所以我们调用PyEval_RestoreThread将我们的线程状态恢复到我们将要终止的线程,然后调用Py_EndInterpreter.
// Acquire the GIL
PyEval_RestoreThread(thread);
// Tear down the interpreter.
Py_EndInterpreter(thread);
// Now what? We still hold the GIL and we no longer have a valid thread state.
// Previously we did PyEval_ReleaseLock here, but that is now deprecated.
Run Code Online (Sandbox Code Playgroud)
的文档PyEval_ReleaseLock说我们应该使用PyEval_SaveThread或PyEval_ReleaseThread。
PyEval_ReleaseThread …
使用 XCode 在 macOS 应用程序项目中嵌入带有 numpy 和 scipy 库的 Python 解释器是否有更简化的过程?我想,更具体地说,嵌入 Python、numpy 和 scipy 库,不会链接到任何获得 GPL 许可的 dylib?
我问的原因是我注意到我的Python源安装中的numpy和scipy文件夹的内容都包含一个dylibs文件夹:
此外,两个库在各自的 License.txt 文件中均指出:
NumPy 的这个二进制发行版还捆绑了以下软件:
名称:GCC 运行时库 文件:.dylibs/* 描述:动态链接到使用 gcc 编译的文件 可用性: https: //gcc.gnu.org/viewcvs/gcc/ 许可证:GPLv3 + 运行时异常
Scipy 的这个二进制发行版还捆绑了以下软件:
名称:GCC 运行时库 文件:.dylibs/* 描述:动态链接到使用 gcc 编译的文件 可用性: https: //gcc.gnu.org/viewcvs/gcc/ 许可证:GPLv3 + 运行时异常
虽然我知道 numpy 和 scipy 是在 BSD 下获得许可的,但我使用这些库的方式需要我必须将 Python 解释器嵌入到我的应用程序包中。所以,我有点茫然,或者也许我只是误解了将 Python 嵌入到应用程序中意味着什么。任何人都可以阐明这种特殊情况吗?
作为额外参考,以下是我在 Cocoa 应用程序中嵌入 Python 时遵循的说明:
如何在 Objective-C OS X 应用程序中嵌入 python 插件?
任何意见都会受到赞赏。谢谢。
python-embedding ×10
python ×9
c ×4
c++ ×3
python-3.x ×3
python-c-api ×2
animation ×1
cpython ×1
macos ×1
matplotlib ×1
numpy ×1
tkinter ×1
xcode ×1
youtube-dl ×1