Returning arguments in SWIG/Python
根据swig文档和在typemap工作中对swig的精彩解释,但是argout不是由@flexo提供的,
我有一个场景,在其中我通过一个EDCOX1,1,然后在EDCOX1,3,3中转换成一个EDCOX1×2,然后在C++ LIB中填充。通过代码,我可以看到映射在从C++返回之后发生了变化,所以我想知道为什么不可能将EDCOX1的2返回到就绪的EDCX1 1中。或者现在有可能,我只是忽略了一些事情?
谢谢!
我有点困惑你到底在问什么,但我的理解是:
- 您有一个"in"类型映射,将Python EDCOX1的0度转换为C++函数
unordered_map ,用于某些函数参数。 - 然后,该函数修改
unordered_map 。 - 完成该函数后,您希望将python
dict 更新为当前的unordered_map ,并且不知何故在该步骤中遇到了问题。 - 既然您知道如何将
dict 转换为unordered_map ,我假设您基本上知道如何使用python c-api将unordered_map 转换回dict ,但不知何故不确定将代码放入哪个swig类型映射。
因此,在这些假设下,我将尽力帮助:
"argout类型映射将引用参数转换为python中的返回值"。不是真的,尽管它主要用于这个目的。一个"AgOutt"类型映射只提供代码来处理一些函数参数(内部称为EDCOX1(9)),在调用C++函数后插入到包装代码中。将此与一个"in"类型映射进行比较,该类型映射提供代码以将提供的Python参数EDCOX1(10)转换成C++参数EDCOX1(9),在调用C++函数之前,它显然被插入到包装代码中。
原来传递的python
dict 在"argout"类型图中称为$input ,修改后的unordered_map 称为$1 (见上面链接的swig文档)。因此,您所需要做的就是为与您已有的"in"类型映射相同的参数签名编写一个"argout"类型映射,并插入代码(使用python c-api)以更新python
dict ($input 的内容,以反映unordered_map 的内容($1 )。请注意,这与传统的"argout"类型映射不同,后者通常会将
$1 转换回新的pythondict ,并将其附加到python返回对象,可以由$result 引用该对象。
我希望这有帮助。如果你在某一点上仍有困难,请编辑你的问题,明确你在哪一点上遇到了困难。
我很清楚用户已经解决了他的问题,但这里有一个解决方案。可以引入一些输入验证,以避免输入字典的非字符串值。
头文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // File: test.h #pragma once #include <iostream> #include <string> #include <unordered_map> void method(std::unordered_map<std::string, std::string>* inout) { for( const auto& n : (*inout) ) { std::cout <<"Key:[" << n.first <<"] Value:[" << n.second <<"] "; } (*inout)["BLACK"] ="#000000"; }; |
接口文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // File : dictmap.i %module dictmap %{ #include"test.h" %} %include"typemaps.i" %typemap(in) std::unordered_map<std::string, std::string>* (std::unordered_map<std::string, std::string> temp) { PyObject *key, *value; Py_ssize_t pos = 0; $1 = &temp; temp = std::unordered_map<std::string, std::string>(); while (PyDict_Next($input, &pos, &key, &value)) { (*$1)[PyString_AsString(key)] = std::string(PyString_AsString(value)); } } %typemap(argout) std::unordered_map<std::string, std::string>* { $result = PyDict_New(); for( const auto& n : *$1) { PyDict_SetItemString($result, n.first.c_str(), PyString_FromString(n.second.c_str())); } } %include"test.h" |
号
试验
1 2 | import dictmap out = dictmap.method({'WHITE' : '#FFFFFF'}) |
输出是更新的字典
1 2 | In[2]: out Out[3] : {'BLACK': '#000000', 'WHITE': '#FFFFFF'} |
。