SWIG有关为C库创建Python绑定的问题

时间:2019-05-29 11:19:44

标签: python c swig python-c-api

我想使用SWIG为C库创建Python绑定,但是我遇到了一些麻烦。我使用了教程中的以下.c和.i文件。 example.c

/* Compute factorial of n */
int fact(int n) {
  if (n <= 1)
    return 1;
  else
    return n*fact(n-1);
}

/* Compute n mod m */
int my_mod(int n, int m) {
  return(n % m);
}

double My_variable;

example.i

%module example
%{
extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);
%}

extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);

我使用的命令:

$ swig -python -py3 example.i
$ gcc -c -fpic example.c example_wrap.c -I/usr/include/python3.6
$ gcc -shared example.o example_wrap.o -o example.so

当我尝试将其导入python3时,我得到了

>>> import example
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_example)

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:1)

SWIG生成一个默认情况下带有下划线的模块,因此您将获得一个名为_example的模块,该模块必须位于_example.so中。

这在SWIG documentation 34.2.3 Hand compiling a dynamic module中有解释:

  

尽管构建扩展模块的首选方法是使用distutils,但有些人喜欢将构建扩展与更大的构建系统集成在一起,因此可能希望在没有distutils的情况下编译其模块。为此,您需要使用如下命令编译程序(针对Linux,显示以下命令):

$ swig -python example.i
$ gcc -O2 -fPIC -c example.c
$ gcc -O2 -fPIC -c example_wrap.c -I/usr/local/include/python2.5
$ gcc -shared example.o example_wrap.o -o _example.so
     

执行此操作的确切命令因平台而异。但是,SWIG会在安装时尝试猜测正确的选项。因此,您可能想从SWIG / Examples / python目录中的示例之一开始。如果这不起作用,则需要阅读编译器和链接器的手册页,以获取正确的选项集。您也可以查看SWIG Wiki,以获取更多信息。

     

链接模块时,输出文件的名称必须与带下划线前缀的模块名称匹配。如果模块的名称为example,则对应的目标文件的名称应为_example.so_examplemodule.so。使用%module指令或-module命令行选项指定模块的名称。

     

兼容性注意:在SWIG-1.3.13和更早的版本中,模块名称不包括前导下划线。这是因为模块通常被创建为仅C扩展,而没有额外的Python支持文件(相反,创建Python代码作为可选功能受支持)。这已在SWIG-1.3.14中更改,并与其他Python扩展模块一致。例如,套接字模块实际上包含两个文件。 socket.py_socket.so。许多其他内置的Python模块遵循类似的约定。