2011-02-15 65 views
4

已经创建了一个C库包括许多源文件和头文件,我现在需要有一个Python层来包装它,这样我就可以“进口”了。Python扩展模块初始化 - 多个文件

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

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

据我所知,如果其他源文件中的方法在C语言中声明为静态(请纠正我,如果我错了),那么就不可能调用其他源文件中的方法,因此,每个C文件只能有一个python模块,因为你只允许一个非静态的方法。

这是真的吗?如果你想从Python访问代码,你必须糟糕地构造你的代码/根本不能?

编辑:

所以,我到底该工作的方法是使用Cython。它不仅需要大约一个小时来重写C/Python接口(其中有先前接受大约一天的时间,由于所有的引用计数规则等),但它也处理所有的建立问题对你来说,并有准确描述清晰的文档,其方法将从python中可用。

特别是,我使用的文档章节是the build instructions,how to call C librariesthe language basicshow to cast types, particularly pointers

对于任何人都希望包装现有复杂结构的C代码作为Python库(即任何超过单个文件更多),我可以强烈建议用Cython。

回答

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); 

anotherunit.c

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

mainunit。 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的顶部也是如此)。

+0

感谢您的回答。这只是C中的常见做法 - 这是我已经如何在文件之间共享函数(包括头文件中的少量预处理器黑客,“#ifndef MYFILE_H #define MYFILE_H 1/* definitions * /#endif`,以防止重复定义)。问题更多的是如何向Python指定编译对象文件中要调用初始化的非静态方法,因为它似乎将所有C源在setup.py中同等重要;因此哪一个是它应该使用的非静态方法。 – tehwalrus 2011-02-16 13:17:12

3

模块初始化函数并不是模块中唯一的非静态符号。它更能防止污染平面命名空间C用于运行时符号的最佳做法。另一种常见的方法是在所有导出的符号上放置一个特定于库的前缀。你可以这样做,虽然通常认为纯静态方法更干净更强大。

+0

感谢您的回答。你如何看待你使用的惯例?你知道这些东西的记录吗? – tehwalrus 2011-02-16 13:19:24

0

所以,我最终得到这个工作的方式是使用Cython。它不仅需要大约一个小时来重写C/Python接口(其中有先前接受大约一天的时间,由于所有的引用计数规则等),但它也处理所有的建立问题对你来说,并有准确描述清晰的文档,其方法将从python中可用。

特别是,我使用的文档章节是the build instructions,how to call C librariesthe language basicshow to cast types, particularly pointers

对于任何人都希望包装现有复杂结构的C代码作为Python库(即任何超过单个文件更多),我可以强烈建议用Cython。