Creating a module for python2 and python3 using SWIG

I have a task where I have to write Python bindings for an existing C ++ library. Since SWIG supports not only Python but languages ​​like Java and Perl, I am using SWIG. I am relatively new to SWIG, so I have my doubts. I want my python library to be supported under Python 2.7 and Python 3.x. But I don't know how to do it. So if anyone can suggest me. Any help would be greatly appreciated. You can ask me for more details if you like.

What I have tried so far.

This is my code file.

/* 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;
}

      

And my interface file

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

      

My steps to compile

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

      

The above compilation format unit works fine with python3 but fails in python2 with error log like

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

      

And if i use below compile command

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

      

Than the module works with python2, but when I try to import into python3 than the error message

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

      

I'm pretty sure the error is because $(pkg-config --cflags --libs pythonX)

I am specifying the version in place of X, but how can I make sure my module works with Python versions?

I tried the -py3

swig flag , but I was unable to make the module work for both Python versions with the above flag.

+3


source to share


1 answer


Expansion

C doesn't work the same in python3 vs python2. This link can help you figure out what you need to do at the C level in order for the library to work for both python 2 and 3 (not using swig). http://python3porting.com/cextensions.html

Using Swig, I would use the pip naming convention: https://packaging.python.org/tutorials/distributing-packages/#packaging-your-project



By doing this, I would package the library for python3 and make the package the following wheel naming standard (" https://www.python.org/dev/peps/pep-0425/#id1 " "py3 -none-any") and then create a library for Python2 and package it using the same strategy ("py2-none-any"). then you can upload it to Pypi and pip will know it needs to use py2 for python2 and py3 for python3.

0


source







All Articles