3

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

5
  • In tester.py what does print(type(a[1])) show? Commented Oct 23, 2019 at 19:12
  • @Flexo <class 'numpy.int64'> Commented Oct 23, 2019 at 19:26
  • That's the problem then, but I'm less sure what the right fix for numpy is. Maybe make the function take int64_t from #include <stdint.h>? Commented Oct 23, 2019 at 20:07
  • you mean change my function to: void print_int(int64_t x); ? When I do that I just get this: TypeError: in method 'print_int', argument 1 of type 'int64_t' Commented Oct 23, 2019 at 20:25
  • Update: I've now copied other swig/numpy.i code on my machine that works for others and I always get the same TypeError. I'm thinking that it's very likely to be the fact that I'm copying over numpy.i from a python2.7 folder, or that there's some other version compatibility issue. Commented Oct 23, 2019 at 21:45

1 Answer 1

4

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)};

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.