5

创建了一个包含许多源文件和头文件的 C 库后,我现在需要用 Python 层包装它,以便“导入”它。

我已经实现了要从 Python 调用的静态方法,我需要指定模块应该向解释器公开哪些方法。

但是,在指定可以调用的内容时,文档似乎只处理具有单个源文件的非常简单的情况,因为唯一的非静态方法必须是注册方法的 init。

据我所知,如果其他源文件中的方法在 C 中声明为静态,则不可能调用它们(如果我在那里错了,请纠正我)所以,每个 python 模块只能有一个 C 文件,因为整个过程中只允许使用一种非静态方法。

真的是这样吗?如果你想从 Python 访问它,你必须把你的代码构造得不好/根本不构造吗?

编辑:

所以,我最终得到这个工作的方式是使用Cython。重写 c/python 接口不仅需要大约一个小时(由于所有引用计数规则等原因,之前需要大约一天时间),而且它还为您处理所有构建问题,并且有清晰的文档准确描述了哪个方法将可从 python 获得。

特别是,我使用的文档章节是构建说明如何调用 C 库语言基础知识以及如何转换类型,尤其是指针

对于希望将现有的复杂结构的 C 代码(即不仅仅是一个文件)包装为 python 库的任何人,我强烈推荐 Cython。

4

3 回答 3

3

模块初始化函数实际上并不是模块中唯一的非静态符号的要求。这更像是一种最佳实践,可以防止污染 C 用于运行时符号的平面命名空间。另一种常见的方法是在所有导出的符号上放置一个库特定的前缀。尽管通常认为仅静态方法更清洁、更健壮,但您可以选择其中任何一种方法。

于 2011-02-15T18:55:13.483 回答
2

使用头文件使编译器可以访问外部函数。这不是与 Python 相关的问题,而是 C 语言中的一个常见方面。

my_prototypes.h

  // declare the prototype. everybody who includes `my_prototypes.h` now knows that it exists.
  PyObject *func_from_other_module(PyObject *self, PyObject *args);

另一个unit.c

  PyObject *func_from_other_module(PyObject *self, PyObject *args) {
    // actual implementation
  }

主单元.c

  #include "my_prototypes.h"

  static PyMethodDef SpamMethods[] = {

    {"func_from_other_module",  func_from_other_module, METH_VARARGS,
      "Blabla"},
    ...
   {NULL, NULL, 0, NULL}        /* Sentinel */
  }

你是对的,如果一个函数被声明static,它只能从它包含的文件中使用。你不需要这个 - 只需离开static(基本上,你甚至不需要标题:放置函数作品顶部的声明mainunit.c也是如此)。

于 2011-02-15T18:48:35.743 回答
0

所以,我最终得到这个工作的方式是使用Cython。重写 c/python 接口不仅需要大约一个小时(由于所有引用计数规则等原因,以前需要大约一天时间),而且它还为您处理所有构建问题,并且有清晰的文档准确描述了哪个方法将可从 python 获得。

特别是,我使用的文档章节是构建说明如何调用 C 库语言基础知识以及如何转换类型,尤其是指针

对于希望将现有的复杂结构的 C 代码(即不仅仅是一个文件)包装为 python 库的任何人,我强烈推荐 Cython。

于 2015-08-22T17:45:43.867 回答