c++ - <Swig 类型为 'std::map< char,int > 的对象的代理

标签 c++ c++11 swig swig-template

从 python 调用以下代码:

from f_p import form_p
print(form_p([1,2,3]))

给我以下错误

错误:

(<f_p.mapiv; proxy of <Swig Object of type 'std::map< char,int > *' at 0x7f09778fc270> >,)

如何解决? 我正在尝试在 swig 中为我的 cpp 代码创建一个包装器。 代码文件:

f_p.i:

%module f_p
#define SWIGPYTHON_BUILTIN

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

%include "std_map.i"
%import "std_deque.i" 
// %include "numpy.i"
%import "std_vector.i" 

#include <deque>

%template() std::vector<int>;

%template (map) std::map<char,int>;
%template(MapDeque) std::deque<std::map<char, int>>;


%include "f_p.h"

f_p.cpp:

#include <deque> 
#include <iostream> 
using namespace std; 

#include <vector>
#include <map>  

deque<map<char, int>> form_p(vector<int> inp_list) 
{
    map<char, int> my_map = {
    { 'A', 1 },
    { 'B', 2 },
    { 'C', 3 }
    };
    deque<map<char, int>> mydeque;
    mydeque.push_back(my_map); 
    return mydeque;
}

f_p.h:

#ifndef F_P_H
#define f_P_H
#include <stdio.h>
#include <deque>
#include <map>
#include <vector>

/* Define function prototype */
std::deque<std::map<char, int>> form_p(std::vector<int> inp_list) ;
#endif

build.sh:

rm *.o f_p_wrap.cpp _f_p.so f_p.py
rm -rf __pycache__

g++ -O3 -march=native -fPIC -c f_p.cpp

swig -python -c++ -o f_p_wrap.cpp f_p.i

# Next, compile the wrapper code:

g++ -O3 -march=native -w -fPIC -c $(pkg-config --cflags --libs python3) -I /home/kriti/anaconda3/lib/python3.7/site-packages/numpy/core/include f_p.cpp f_p_wrap.cpp

g++ -std=c++11 -O3 -march=native -shared f_p.o f_p_wrap.o -o _f_p.so -lm

我无法获得输出。我不知道如何使用双端队列。对于 map 和 vector ,我可以生成结果,但不能使用双端队列以及 map 中存在字符时。

最佳答案

您标记为“错误”的是正确的(或至少是预期的)结果:双端队列被转换为 Python 元组。要访问您的 map ,只需访问第一个元素,然后访问 map 即可:

>>> from f_p import form_p
>>> print(form_p([1,2,3]))
(<f_p.map; proxy of <Swig Object of type 'std::map< char,int > *' at 0x7f16259a1c60> >,)
>>> d = form_p([1,2,3])
>>> len(d)
1
>>> d[0]
<f_p.map; proxy of <Swig Object of type 'std::map< char,int > *' at 0x7f16259aeb40> >
>>> m = d[0]
>>> len(m)
3
>>> m.keys()
['A', 'B', 'C']
>>> m['B']
2
>>> for m in d:
...     print m.keys()
... 
['A', 'B', 'C']
>>> 

编辑:根据评论进行跟进。 std::deque 已经有一个“out”类型映射。 ,不幸的是,它匹配得更紧密,所以除非您指定 std::deque<std::map<char, int>> form_p完全(即使用函数名称),它将不匹配,因此以下示例使用“ret”代替,以应用于返回此类双端队列的所有函数。添加到 f_p.i:

%typemap(ret) std::deque<std::map<char, int>> {
  $result = PyTuple_New($1.size());
  for (int i = 0; i < (int)$1.size(); ++i)
    PyTuple_SetItem($result, i, swig::traits_from<std::map<char, int>>::asdict($1[i]));
}

此代码创建一个元组(如果您更喜欢 python 列表,请使用 PyList_NewPyList_SetItem),然后循环遍历双端队列中的条目并将它们转换为 python 字典。 asdict call 是一个生成的 python 函数,如果您愿意,也可以在 .i 中的 python 后处理代码中使用它。

完成后,结果是:

>>> from f_p import form_p
>>> print(form_p([1,2,3]))
({'A': 1, 'C': 3, 'B': 2},)
>>> 

关于c++ - <Swig 类型为 'std::map< char,int > 的对象的代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59646517/

相关文章:

java - SWIG,我可以为从 Java 传递到 C 的 char** 赋值吗

c++ - 设置精度和 float

c++ - 无法将 uint8_t vector 迭代器转换为 const uint8_t *

c++ - 在静态变量定义中捕获的引用

c++ - C++ 中的分配器用法(STL 树)

c - 错误: Stray '#" in program (SWIG)

java - 管理供 Java GUI 使用的 C++ API 的 Java 包装 : proper version control

c++ - 当为不存在的日期/时间设置 CreateWaitableTimer 时会发生什么?

c++ - 在 C++ 中,以这种方式包括有问题吗?

c++ - std::find_if_not() 返回什么类型?