使用SWIG

时间:2017-05-10 11:30:06

标签: python python-2.7 python-3.x swig

我有一个任务,我必须为现有的C ++库编写Python绑定。由于SWIG不仅支持Python,还支持Java和Perl等语言,因此我使用的是SWIG。我在SWIG比较新,所以我有一个疑问。我希望我的python库在Python 2.7和Python 3.x下可以支持。但我不知道如何做到这一点。所以,如果有人可以建议我。任何帮助,将不胜感激。如果需要,您可以向我询问更多详细信息。

到目前为止我的尝试。

这是我的代码文件。

/* example.c file */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int my_mod(int n, int m) {
      return n % m;
}

int sieve(int number) {
    int* arr = malloc(sizeof (int) * (number + 10));
    int* prime = malloc(sizeof (int) * (number + 10));
    /* printf("Size of arr: %lu", sizeof(arr));
      printf("Size of int: %lu", sizeof(int)); */
    memset(arr, 0, sizeof(int) * (number + 10));
    int counter = 0;
    prime[counter++] = 2;
    arr[0] = arr[1] = 0;
    for (int i = 3; i * i <= number; i += 2) {
        if (!arr[i]) {
            for (int j = i + i; j < number; j += i) {
            arr[j] = 1;
        }
    }
  }
  for (int i = 3; i < number; i += 2)
      if (!arr[i])
  prime[counter++] = i;
  // free(arr);
  // free(prime);
  return counter;
}

我的界面文件是

/* example.i */
%module example
%{
      #include "stdio.h"
      #include "stdlib.h"
      #include "string.h"
      extern int my_mod(int n, int m);
      extern int sieve(int number);
%}

extern int my_mod(int n, int m);
extern int sieve(int number);

我的编译步骤

swig -python example.i
gcc -fpic -c example.c example_wrap.c $(pkg-config --cflags --libs python3)
gcc  -shared  example.o example_wrap.o -o _example.so

在上面的编译格式模块中使用python3工作正常,但在python2中失败,错误日志为

ImportError: ./_example.so: undefined symbol: PyUnicode_FromFormat

如果我使用以下编译命令

swig -python example.i
gcc -fpic -c example.c example_wrap.c $(pkg-config --cflags --libs python2)
gcc  -shared  example.o example_wrap.o -o _example.so

比模块正在使用python2但是当我尝试在python3中导入而不是错误消息是

ImportError: /home/deepanshu/env/swig/env/src/deep/_example.so: undefined symbol: PyInstance_Type

我确定错误是因为$(pkg-config --cflags --libs pythonX)我在X的位置指定版本但是如何确保我的模块适用于两个Python版本?

我尝试了swig的-py3标志,但我无法使模块适用于具有上述指定标志的Python版本。

1 个答案:

答案 0 :(得分:0)

C扩展在python3与python2中的工作方式不同。此链接可以帮助您确定在C级别上需要执行的操作,以使库适用于python 2和3(不使用swig)。 http://python3porting.com/cextensions.html

使用Swig,我要做的是使用pip轮子命名约定: https://packaging.python.org/tutorials/distributing-packages/#packaging-your-project

这样做,我会将库打包为python3并使包遵循轮命名标准(&#34; https://www.python.org/dev/peps/pep-0425/#id1&#34;&#34; py3-none-any&#34;)和然后为Python2创建库并使用相同的策略打包它(&#34; py2-none-any&#34;)。然后你可以将它上传到Pypi并且pip会知道它需要使用py2 for python2和py3 for python3。