|
11 | 11 | ----------
|
12 | 12 | 解决方案
|
13 | 13 | ----------
|
14 |
| -在C语言中调用Python非常简单,不过设计到一些小窍门。 |
| 14 | +在C语言中调用Python非常简单,不过涉及到一些小窍门。 |
15 | 15 | 下面的C代码告诉你怎样安全的调用:
|
16 | 16 |
|
17 |
| -:: |
| 17 | +:: c |
18 | 18 |
|
19 | 19 | #include <Python.h>
|
20 | 20 |
|
|
75 | 75 | 有很多种方法可以让你这样做,
|
76 | 76 | 比如将一个可调用对象传给一个扩展模块或直接写C代码从已存在模块中提取出来。
|
77 | 77 |
|
78 |
| -下面是一个简单例子用来掩饰从一个嵌入的Python解释器中调用一个函数: |
| 78 | +下面是一个简单例子用来展示从一个嵌入的Python解释器中调用一个函数: |
79 | 79 |
|
80 | 80 | ::
|
81 | 81 |
|
|
214 | 214 | 第二个函数相对安全点,因为它允许传递NULL指针(直接忽略它),
|
215 | 215 | 这也是为什么我们使用它来清理可选的关键字参数。
|
216 | 216 |
|
217 |
| -调用万Python函数之后,你必须检查是否有异常发生。 |
| 217 | +调用完Python函数之后,你必须检查是否有异常发生。 |
218 | 218 | ``PyErr_Occurred()`` 函数可被用来做这件事。
|
219 |
| -对对于异常的处理就有点麻烦了,由于是用C语言写的,你没有像Python那么的异常机制。 |
| 219 | +对于异常的处理就有点麻烦了,由于是用C语言写的,没有Python那样的异常机制。 |
220 | 220 | 因此,你必须要设置一个异常状态码,打印异常信息或其他相应处理。
|
221 | 221 | 在这里,我们选择了简单的 ``abort()`` 来处理。另外,传统C程序员可能会直接让程序奔溃。
|
222 | 222 |
|
|
265 | 265 | 一旦返回,``PyGILState_Ensure()`` 可以确保调用线程独占Python解释器。
|
266 | 266 | 就算C代码运行于另外一个解释器不知道的线程也没事。
|
267 | 267 | 这时候,C代码可以自由的使用任何它想要的Python C-API 函数。
|
268 |
| -调用成功后,PyGILState_Release()被用来讲解释器恢复到原始状态。 |
| 268 | +调用成功后,PyGILState_Release()被用来将解释器恢复到原始状态。 |
269 | 269 |
|
270 | 270 | 要注意的是每一个 ``PyGILState_Ensure()``
|
271 | 271 | 调用必须跟着一个匹配的 ``PyGILState_Release()`` 调用——即便有错误发生。
|
272 | 272 | 在这里,我们使用一个 ``goto`` 语句看上去是个可怕的设计,
|
273 |
| -但是实际上我们使用它来讲控制权转移给一个普通的exit块来执行相应的操作。 |
274 |
| -在 ``fail:`` 标签后面的代码和Python的 ``fianl:`` 块的用途是一样的。 |
| 273 | +但是实际上我们使用它来将控制权转移给一个普通的exit块来执行相应的操作。 |
| 274 | +在 ``fail:`` 标签后面的代码和Python的 ``final:`` 块的用途是一样的。 |
275 | 275 |
|
276 | 276 | 如果你使用所有这些约定来编写C代码,包括对GIL的管理、异常检查和错误检查,
|
277 | 277 | 你会发现从C语言中调用Python解释器是可靠的——就算再复杂的程序,用到了高级编程技巧比如多线程都没问题。
|
|
0 commit comments