如何在Swig中包装包含int和int向量的地图?

时间:2019-07-19 10:26:37

标签: python c++ swig

我想使用Swig将哈希图从C ++返回到Python。 我能够打印键,但无法获取值。它给了我这个输出:

{0: <Swig Object of type 'std::vector< int,std::allocator< int > > *' at 0x7fa646cdfcf0>,
 1: <Swig Object of type 'std::vector<int,std::allocator< int > > *' at 0x7fa646371150>}
<Swig Object of type 'std::vector< int,std::allocator< int > > *' at 0x7fa646cdfcf0>

如何获取值代替swig对象。我可以使用map <int, int>,但是不能使用map<int, vector<int> >。 我找到了最接近它的github issue,但这无济于事,因为我无法理解如何在代码中使用它。抱歉,我是初学者,请帮忙。

myknn.cpp

// Example program
#include <cstdlib>
#include <algorithm>
#include <numeric>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <chrono>
#include <random>
#include <map>
#include <cmath>
#include <map>
#include <math.h>

std::vector<int> argsort(double* input_list, int length) {

    std::vector<int> out(length);
    iota(out.begin(), out.end(), 0);
    sort(out.begin(), out.end(),
       [&input_list](int i1, int i2) {return input_list[i1] < input_list[i2];});
    return out;
}

double edist(double* arr1, double* arr2, int n) {
    double sum = 0.0;
    for (int i=0; i<n; i++) {
        sum += pow(arr1[i] - arr2[i], 2);
    }
    return sqrt(sum); 
}

std::map<int, std::vector<int> > distance_knn(const double *array,int N, int M) {
     std::map<int, std::vector<int> > dist;
    double **arr = new double*[N];
    for (int i = 0; i < N; i++) {
        arr[i] = new double[M];
        for(int j=0; j < M; j++) {
            arr[i][j] = array[i*M+j];
        }
    }

     for (int i=0; i<N; i++) {
        double distances[N];
        for(int j=0; j<N; j++) {
            // distances.push_back();
            distances[j] = edist(arr[i], arr[j], N);
        }
        dist[i] = argsort(distances, N);
    }

    return dist;
}

myknn.i

%module myknn

%{
  #define SWIG_FILE_WITH_INIT  /* To import_array() below */
  #include "myknn.h"
%}

%include "numpy.i"

/* Required for the NumPy C API. Calls to PyArray_SimpleNew
   will result in a segfault if this is omitted */

%include "std_map.i"
%import "std_vector.i" 
namespace std {
// %template (IntVector) std::vector<int>
 %template (mapiv) std::map<int,vector<int> >;
// %template (IntVector) std::vector<int>;
// %template (MapType) std::map<int, IntVector>;
}

%init %{
import_array();
%}

%apply (double* IN_ARRAY2, int DIM1, int DIM2) {
  (const double* array, int m, int n)
}

%include "myknn.h"

myknn.h

/* File knn.h */

#ifndef KNN_H
#define KNN_H
#include <stdio.h>
#include <vector>
#include <map>

/* Define function prototype */
std::map<int,std::vector<int> > distance_knn(const double* array,int m, int n);
std::vector<int> argsort(double* input_list, int length);
double edist(double* arr1, double* arr2, int n);


#endif

build.sh

g++ -fPIC -c myknn.cpp

# Invoke SWIG on the interface file 'knn.i' to produce C/C++ wrapper
# code ('knn_wrap.cpp'):

swig -python -c++ -o myknn_wrap.cpp myknn.i

# Next, compile the wrapper code:

g++ -fPIC -c $(pkg-config --cflags --libs python3) -I /home/kriti/anaconda3/lib/python3.7/site-packages/numpy/core/include  myknn_wrap.cpp

# Link both object files into a shared library '_myknn.so'.
# Python will search for it under this name:

g++ -shared myknn.o myknn_wrap.o -o _myknn.so -lm

main.py

import numpy as np
from myknn import distance_knn

a = np.array([[1,2,3,4], [4,5,6,7]], np.float32)

arr = distance_knn(a)
print(dict(arr))
print(arr[0])

要运行:

  
    

bash build.sh

         

python main.py

  

规格:

Python 3.7.3

SWIG版本3.0.12

使用g ++ [x86_64-pc-linux-gnu]编译

配置的选项:+ pcre

0 个答案:

没有答案