0

I am trying to wrap c++ functions into python using swig. I am using following commands

swig -c++ -python helloworld.i
g++ -O2 -fPIC -c hello.cpp
g++ -O2 -fPIC -c helloworld_wrap.cxx -I//anaconda/include/python2.7
g++ -lpython -dynamclib hello.o helloworld_wrap.o -o _helloworld.so

with hello.cpp being initial file with functions and helloworld.i being file with wrapper. These commands creates the library helloworldbut I can only import it through default python in /usr/bin/python

If I try to import it through python installed through anaconda it gives following error:

Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6  

Can you tell me how can I wrap the codes with python from anaconda?

Found a solution : Python.h not found using swig and Anaconda Python

In above question, the top answer gives an explanation of using disutilsand a set up file in python to build the library. This works wonders :)

The next problem I am having for wrapping simple class:

my class code from [example] (http://web.mit.edu/svn/src/swig-1.3.25/Examples/python/class/index.html)

/* File : example.h */

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area() = 0;
  virtual double perimeter() = 0;
  static  int nshapes;
};

class Circle : public Shape {
    private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area();
  virtual double perimeter();
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area();
  virtual double perimeter();
};  

My setup.py file :

#setup.py file:

from setuptools import setup, Extension

setup(name='example',

    version='0.1',

    ext_modules=[Extension('_example', ['example.h', 'example.i'],
                swig_opts=['-c++'],
                )],

    )  

Code I am using to wrap :

python setup.py build_ext --inplace  

Error message:

running build_ext
building '_example' extension
swigging example.i to example_wrap.cpp
swig -python -c++ -o example_wrap.cpp example.i
error: unknown file type '.h' (from 'example.h')  

Can you suggest what is wrong here. I suppose it is not recognizing '.h' file but as it is header file, I thought it could be kept as it is. Also if my setup.py file is correct or not? I am just trying to follow example for simple wrapping, there is no simple tutorial online apparently.
I can also ask this question on other different question but thought just continuing here for now.

Community
  • 1
  • 1
jkhadka
  • 2,443
  • 8
  • 34
  • 56
  • Yes, the answer you cite perfectly answers your question (using distutils and even without). So what exactly is the point of posting your question if you already know the answer? – m7thon Nov 23 '15 at 20:54
  • @m7thon I actually first posted the question and quite a bit later found the solution. So I just added the solution here too. Should I take the question down ? Or how do i say it is closed? – jkhadka Nov 24 '15 at 10:33
  • I see. I guess the best is to just post your found solution as an answer. Then it is clear that the question really is answered. – m7thon Nov 24 '15 at 11:33
  • okay thank you :) also I wanted to ask few things to you about C++ class wrapping as you seem to be quite knowledgeable in this field. I have classes that has a lot of inheritance to wrap but I am right now trying to work on basic class mainly with this [example](http://web.mit.edu/svn/src/swig-1.3.25/Examples/python/class/index.html) I have added my `setup.py` file that I am using also above and the error I am getting, can you suggest me what is happening. As I told you before I am very new at this and do not have much knowledge in the field. Any help will be well appreciated. :) – jkhadka Nov 24 '15 at 13:56
  • To ask a new question, you should start a new one. Just quickly, as you guessed, you should not be compiling header files. The source files listed in setup.py for your extension should be example.cpp and example.i. – m7thon Nov 24 '15 at 21:24
  • Please do read the swig documentation. It is very good. For your compilation issues, see for instance the part [here](http://www.swig.org/Doc3.0/SWIGDocumentation.html#Python_nn6). – m7thon Nov 24 '15 at 21:25
  • Thank you for the help. I will try to work it out and if something is wrong will post new question. You have been quite helpful and generous with your suggestions :)Thanks – jkhadka Nov 25 '15 at 11:06
  • @m7thon I got the solution for the above problem with `unknown file type '.h'`apparently I should include the options `headers = ['header/location/header.h']` as `setup(...., headers=[..])` in `setup.py` seems strange that python disutils file description does not cover this point. – jkhadka Nov 25 '15 at 13:07

1 Answers1

0

Answer by Warren Weckesser in similar question . I used the setup.py file as suggested in the answer and added the path to the library to sys.path and it work wonders :)

Use the option -I/Users/myuser/anaconda/include/python2.7 in the gcc command. (That's assuming you are using python 2.7. Change the name to match the version of python that you are using.) You can use the command python-config --cflags to get the full set of recommended compilation flags:

$ python-config --cflags
-I/Users/myuser/anaconda/include/python2.7 -I/Users/myuser/anaconda/include/python2.7 -fno-strict-aliasing -I/Users/myuser/anaconda/include -arch x86_64 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes

However, to build the extension module, I recommend using a simple setup script, such as the following setup.py, and let distutils figure out all the compiling and linking options for you.

# setup.py

from distutils.core import setup, Extension


example_module = Extension('_example', sources=['example_wrap.c', 'example.c'])

setup(name='example', ext_modules=[example_module], py_modules=["example"])

Then you can run:

$ swig -python example.i
$ python setup.py build_ext --inplace

(Take a look at the compiler commands that are echoed to the terminal when setup.py is run.)

distutils knows about SWIG, so instead of including example_wrap.c in the list of source files, you can include example.i, and swig will be run automatically by the setup script:

# setup.py

from distutils.core import setup, Extension


example_module = Extension('_example', sources=['example.c', 'example.i'])

setup(name='example', ext_modules=[example_module], py_modules=["example"])

With the above version of setup.py, you can build the extension module with the single command

$ python setup.py build_ext --inplace

Once you've built the extension module, you should be able to use it in python:

>>> import example
>>> example.fact(5)
120

If you'd rather not use the script setup.py, here's a set of commands that worked for me:

$ swig -python example.i
$ gcc -c -I/Users/myuser/anaconda/include/python2.7 example.c example_wrap.c 
$ gcc -bundle -undefined dynamic_lookup -L/Users/myuser/anaconda/lib example.o example_wrap.o -o _example.so

Note: I'm using Mac OS X 10.9.4:

$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
Community
  • 1
  • 1
jkhadka
  • 2,443
  • 8
  • 34
  • 56