【发布时间】:2019-05-05 16:51:01
【问题描述】:
我尝试将 Python 解释器嵌入到 C 中。 为了对此进行测试,我创建了一个共享库并 尝试使用 ctypes 在 Python 中加载这个。不幸的是,这并没有 工作,我想了解原因。
这是一个示例 c - 代码:
#ifdef __cplusplus
extern "C" {
#endif
#include <Python.h>
int run_py(void);
int run_py2(void);
int
run_py(void)
{
printf("hello from run_py\n");
return 42;
}
int
run_py2(void)
{
printf("entering c-function: run_py()\n");
Py_Initialize();
PyRun_SimpleString("print('hello world')");
return 0;
}
#ifdef __cplusplus
}
#endif
所以我用 gcc 将它编译成“mylib.so”,并使用 python3.7-config --cflags 和 --ldflags 进行链接等等。
这是我用来加载它的 Python 代码..
import ctypes as c
import os
import sys
if __name__ == '__main__':
print("running shared-lib integration test with python:\n{}".format(sys.version))
path = os.path.dirname(os.path.realpath(__file__))
dllfile = os.path.join(path, 'mylib.so')
dll = c.CDLL(str(dllfile))
print("loaded CDLL")
dll.run_py.restype = c.c_int
dll.run_py2.restype = c.c_int
print("now calling dll.run_py()...")
rv = dll.run_py()
print("called dll.run_py: rv={}".format(rv))
print("now calling dll.run_py2()...")
rv2 = dll.run_py2()
print("called dll.run_py2: rv={}".format(rv2))
所以这只是加载两个函数 run_py 和 run_py2 并执行它们。这是输出...
running shared-lib integration test with python:
3.7.1 (default, Oct 22 2018, 10:41:28)
[GCC 8.2.1 20180831]
loaded CDLL
now calling dll.run_py()...
hello from run_py
called dll.run_py: rv=42
now calling dll.run_py2()...
entering c-function: run_py()
Segmentation fault (core dumped)
所以基本上这会导致调用 run_py2 时出现段错误。
造成这种情况的原因是 PyRun_SimpleString 的调用。
但是,如果我将其编译为独立的 C 程序
一切似乎都很好。我真的
想了解为什么会发生这种情况......但目前我
出了一些想法,所以在这里非常感谢任何反馈。
BR jrsm
【问题讨论】:
-
看起来你正在混合两种不同的东西,嵌入 Python 和扩展 Python。如果你的库扩展了 Python(即可以从 Python 中加载),你不应该尝试在其中嵌入 Python 解释器(除非你想要两个独立的不相关的 Python 解释器,我对此表示怀疑)。
-
是的,你是对的,最后我不会使用两个 python 解释器......只有 C 中的共享库(所以 Python 嵌入在 C 中)。但是,我尝试将此作为第一次测试(出于好奇),现在我想了解它为什么会损坏;-)