pythonc++numpyswigtypemaps

Passing numpy array element (int) to c++ int using SWIG


I'd like to pass an integer element from a numpy array in python to a c++ function that catches it as a c++ integer using SWIG.

What am I missing here?

add_vector.i

%module add_vector
%{
    #define SWIG_FILE_WITH_INIT
    #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION  // gets rid of warning
    #include "add_vector.h"
%}

%include "numpy.i"
%init %{
import_array();
%}

%include "add_vector.h"

add_vector.h

#include <iostream>

void print_int(int x);

add_vector.cpp

#include "add_vector.h"

void print_int(int x) {
    std::cout << x << std::endl;
}

tester.py

import add_vector as vec
import numpy as np

a = np.array([1,2,3])
print(a[1])
vec.print_int(a[1])

OUTPUT

2
Traceback (most recent call last):
  File "tester.py", line 6, in <module>
    vec.print_int(a[1])
TypeError: in method 'print_int', argument 1 of type 'int'

Reading from the numpy.i manual (https://docs.scipy.org/doc/numpy-1.13.0/reference/swig.interface-file.html#numpy-array-scalars-and-swig), I copied the pyfragments.swg file into my working directory, but nothing changed.

I've also tried a number of %apply directives both for passing an int and an int *, but that hasn't yet changed anything. I keep getting the same TypeError I listed above.

Versions: numpy 1.17.3 ; swig 2.0.12 ; python 3.7.3 ; numpy.i is being copied into my working directory from: /usr/lib/python2.7/dist-packages/instant/swig/numpy.i


Solution

  • Solved! There were 3 issues:

    1. The numpy.i file I copied over isn't compatible, and the compatible version isn't included in the installation package when you go through anaconda (still not sure why they'd do that).

    Answer: Find which version of numpy you're running, then go here (https://github.com/numpy/numpy/releases) and download the numpy-[your_version].zip file, then specifically copy the numpy.i file, found in numpy-[your_version]/tools/swig/. Now paste that numpy.i into your project working directory.

    1. As a default, numpy makes integers of type long. So in tester.py file, I needed to write: a = np.array([1,2,3], dtype=np.intc)

    2. Need to convert numpy int to c++ int in add_vector.i. This can be done by using the %apply directive right above the %include "add_vector.h" line: %apply (int DIM1) {(int x)};