6

只是为了它,我决定创建一个与 libpython 的 Scheme 绑定,以便您可以将 Python 嵌入到 Scheme 程序中。我已经能够调用 Python 的 C API,但我还没有真正考虑过内存管理。

mzscheme 的 FFI 的工作方式是我可以调用一个函数,如果该函数返回一个指向 a 的指针PyObject,那么我可以让它自动增加引用计数。然后,我可以注册一个终结器,它会在 Scheme 对象被垃圾回收时减少引用计数。我查看了有关引用计数的文档,乍一看并没有发现任何问题(尽管在某些情况下它可能不是最佳的)。我有什么遗漏吗?

另外,我在制作循环垃圾收集器文档的正面或反面时遇到了麻烦。在这里我需要记住什么?特别是,我如何让 Python 知道我引用了某些东西,以便在我仍在使用它时它不会收集它?

4

2 回答 2

8

您指向http://docs.python.org/extending/extending.html#reference-counts的链接是正确的地方。文档的扩展和嵌入以及 Python/C API 部分将解释如何使用 C API。

引用计数是使用 C API 的烦人部分之一。主要问题是保持一切正常:根据您调用的 API 函数,您可能拥有也可能不拥有对所获得对象的引用。请注意了解您是拥有它(因此不能忘记 DECREF 或将其交给会窃取它的东西)还是借用它(并且必须 INCREF 以保留它并可能在您的函数期间使用它)。涉及此问题的最常见错误是 1) 错误地记住您是否拥有由特定函数返回的引用,以及 2) 认为您可以安全地借用引用的时间比实际时间长。

您不必为循环垃圾收集器做任何特别的事情。它只是用来修补引用计数中的缺陷,不需要直接访问。

于 2010-05-29T14:08:35.553 回答
3

引用计数和 C API 是我所知道的最大问题__del__。当你有一个借来的引用时,你认为你可以在没有 INCREF'ing 的情况下逃脱,因为你在使用那个引用时没有放弃 GIL。但是,如果您最终删除了一个对象(例如,通过从列表中删除它),您可能会触发一个__del__调用,这可能会删除您从脚下借用的引用。非常棘手。

如果您在获得所有借用的引用后立即 INCREF(然后当然是 DECREF),那么应该没有任何问题。

于 2010-05-29T14:48:14.390 回答