“c 调用python出现异常的原因分析”攻略
1. 异常出现的原因
在使用 C 语言调用 Python 时,出现异常的原因可能有以下几种情况:
- Python 环境没有正确初始化。调用 Python API 前应先使用
Py_Initialize()
函数初始化 Python 环境,否则会出现异常; - 使用 Python 时,需要保证全局解释器锁(GIL)已经被正确初始化。GIL 是为了保证多线程访问 Python 环境的安全的机制。可以使用
PyEval_InitThreads()
来初始化 GIL; - Python 程序运行中抛出异常。在 C 语言中调用 Python 时,可以使用
PyErr_Occurred()
函数来判断 Python 程序是否抛出异常。
2. 示例说明
下面给出两个例子,说明 C 语言调用 Python 时出现异常的原因和解决方法。
示例1
当 Python 环境没有正确初始化时,会出现如下异常:
Fatal Python error: Py_Initialize: unable to load the file system codec
ImportError: No module named 'encodings'
这时需要在调用 Python API 前,使用 Py_Initialize()
函数来初始化 Python 环境。示例代码如下:
#include <Python.h>
int main() {
// 初始化 Python 环境
Py_Initialize();
// 调用 Python API
...
// 关闭 Python 环境
Py_Finalize();
return 0;
}
示例2
在使用多线程时,需要保证 GIL 已经被正确初始化。否则,会出现 PyEval_AcquireThread()
调用返回 NULL 的现象,从而导致 Python 程序无法运行。示例代码如下:
#include <Python.h>
#include <pthread.h>
void* py_thread(void* arg) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
// 调用 Python API
...
PyGILState_Release(gstate);
return NULL;
}
int main() {
// 初始化 Python 环境
Py_Initialize();
// 初始化 GIL
PyEval_InitThreads();
// 创建线程
pthread_t tid;
pthread_create(&tid, NULL, &py_thread, NULL);
// 等待线程结束
pthread_join(tid, NULL);
// 关闭 Python 环境
Py_Finalize();
return 0;
}
在主线程中使用 PyEval_InitThreads()
函数初始化 GIL,然后在新线程中使用 PyGILState_Ensure()
函数获取全局解释器锁,以便在该线程中调用 Python API。