Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling SWIG wrapper for python in Windows

First, thank all of you for all the answer you gave me on this forum the last years, but today I couldn't find a clear answer and so I though It was time to post.

I manage to compile and run a C++ code test5.cpp on my Debian distrib, wrapping it ( maybe it's not the right word) into a python module Amod.py with SWIG ( which necessitate a "translation" file test5.i .I used and import successfully the module for data analysis into other more complex python code ( basically manipulation of numpy array, matplotlib and so on..).

Now I want run the same code on a Windows computer but then python cannot import the module anymore, the librairy file _Amod.so is a .so file, and not .pyd as windows expect. But I cannot find a quick and easy way to recompile it on Windows. I dig the CodeBlocks docs, but its lacunary, i am lost. ( http://wiki.codeblocks.org/index.php?title=Adding_support_for_non_C/C%2B%2B_files_to_the_build_system )

Basically I would like to run the Windows equivalent of the working code below (wich I hope can help beginner is SWIG) :

Compilation :

swig -c++ -python test5.i
g++ -fPIC -c test5.cpp
g++ -fPIC -c test5_wrap.cxx -I/usr/include/python2.7
g++ -shared test5.o test5_wrap.o -o _Amod.so

Wich software and compiler should I use, and how, without losing my time ? (I got CodeBlocks already) Thank you very much.

For information if needed, the test5.i is the following, wrapping C++ array in numpy array, adding some inline (replace functions) for checking purpose (all was dig into swig help with blood and tears):

/* %module module_name is used in compilation as: g++ -shared main.o main_wrap.o -o _module_name.so (with the underscore)*/
%module Amod

%{
/* Put header files here or function declarations like below. The #define SWIG_FILE_WITH_INIT line inserts a macro that specifies that the resulting C file should be built as a python extension, inserting the module init code. check http://www.swig.org/Doc1.3/Python.html#Python_nn3 */
#define SWIG_FILE_WITH_INIT
#include "test5.h"
%}

/* numpy.i and import_array() allow SWIG to manipulate C++ pointer (like double* ivec) like numpy array, because SWIG doesn't know a priori, that the pointer refer to an array. check http://docs.scipy.org/doc/numpy/reference/swig.interface-file.html */

%include "numpy.i"

%init %{
import_array();
%}


/* C++ function arg must fits the typemap directives available in numpy.i. */

%apply (int DIM1, double* INPLACE_ARRAY1) {(int len1, double* ivec),(int len2, double* ovec),(int len3, double* gauss)};
%rename (abel) abel_swig;
%exception abel_swig {
    $action
    if (PyErr_Occurred()) SWIG_fail;
}
%inline %{
void abel_swig(int len1, double* ivec, int len2, double* ovec, int algo, double alpha) {
    if (len1 != len2) {
        PyErr_Format(PyExc_ValueError,"Arrays of lengths (%d,%d) given",len1, len2);
        return;
    }
    memset(ovec, 0, len1*sizeof(double));
    return abel(len1, ivec, len2, ovec, algo, alpha);
}
%}


%rename (convol_gauss) convol_gauss_swig;
%exception convol_gauss_swig {
    $action
    if (PyErr_Occurred()) SWIG_fail;
}
%inline %{
void convol_gauss_swig(int len1, double* ivec, int len2, double* ovec, int len3, double* gauss) {
    if ((len1 != len2)||(len1 != len3)) {
        PyErr_Format(PyExc_ValueError,"Arrays of lengths (%d,%d,%d) given, they must be the same",len1, len2, len3);
        return;
    }
    memset(ovec, 0, len1*sizeof(double));
    return convol_gauss(len1, ivec, len2, ovec, len3, gauss);
}
%}


/* Put header files here or function declarations like below */

%include "test5.h"

and the header test5.h:

#ifndef TEST5_H_INCLUDED
#define TEST5_H_INCLUDED
#include <cstring>
#include <iostream>
#include <cmath>
void convol_gauss(int size, double* ivec, int size2, double* ovec, int size3, double* gauss);
void abel(int len1, double* ivec, int len2, double* ovec, int algo);

#endif // TEST5_H_INCLUDED
like image 762
Florian M. Avatar asked Feb 24 '26 05:02

Florian M.


1 Answers

Ok, I managed to do it.

1- Take care that you .i files are encoded in utf-8, as it prevented swig to compile if Python as a different encoding.( #error Must use Python with unicode enabled )

2- Download swig for Windows on www.swig.org and installing MinGW

3- type in cmd or Powershell

swig -c++ -python test5.i
g++ -c -Wall test5.cpp
g++ -c -Wall test5_wrap.cxx -I C:\Python27\include -I C:\Python27\Lib\site-packages\numpy\core\include\
g++ -Wall -shared -I C:\Python27\include -I C:\Python27\Lib\site-packages\numpy\core\include\ test5.o test5_wrap.o -o _Amod.pyd -L C:/Python27/libs/ -lpython27

-I C:\Python27\Lib\site-packages\numpy\core\include\ solve the Error : fatal error : numpy\arrayobject.h no such file or directory

-L C:/Python27/libs/ -lpython27 solve the Error : undefined reference to _imp__Py...

Contrary to the Linux compilation, the library C:/Python27/libs/python27.lib has to be carefully linked, as well as the directores of the headers (C:\Python27\include and for numpy C:\Python27\Lib\site-packages\numpy\core\include) Hope it can helps, but I don't have the feeling it's a very clean job. See this previous post considering the errors I met.

like image 150
Florian M. Avatar answered Feb 26 '26 19:02

Florian M.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!