Вот пример того, как вы можете использовать %typemap
для вложенного std::map
.
new_tr.i :
%module new_tr
%typemap(out) std::map<int, std::map<std::string,std::string>> {
HV *hash = (HV *) newHV();
for (auto const& item : $1) {
HV *subhash;
char *keysv;
auto map = item.second;
subhash = (HV *) newHV();
for (auto const &item2 : map) {
SV *sv;
auto key2 = item2.first.c_str();
auto value = item2.second.c_str();
sv = newSVpvn( value, strlen(value) );
hv_store (subhash, key2, strlen(key2), sv, 0);
}
auto key = std::to_string(item.first).c_str();
hv_store (hash, key, strlen(key), (SV*) newRV_noinc((SV*)subhash), 0);
}
$result = newRV_noinc((SV*) hash);
sv_2mortal($result);
argvi++;
}
%{
#include "new_tr.h"
%}
%include "new_tr.h"
new_tr.h :
#include <map>
#include <string>
using ssmap = std::map<int, std::map<std::string,std::string>>;
ssmap getResult();
new_tr.cxx :
#include "new_tr.h"
ssmap getResult()
{
ssmap map = {
{1, {{"Brown","Manager"}, {"Smith", "Salesman"}, {"Albert", "Salesman"}}},
{2, {{"Penfold", "Designer"}, {"Evans", "Tea-person"}, {"Jurgens", "Manager"}}}
};
return map;
}
Затем скомпилируйте модуль с помощью:
perl_include_dir=$(perl -MConfig -e'print $Config{archlib}')"/CORE"
swig -perl5 -c++ -I/usr/include new_tr.i
g++ -fPIC -c new_tr.cxx
g++ -I${perl_include_dir} -c -fPIC -g -o new_tr_wrap.o new_tr_wrap.cxx
g++ -shared -L. new_tr.o new_tr_wrap.o -o new_tr.so
и протестируйте его с помощью test.pl :
use strict;
use warnings;
use Data::Dumper;
use lib '.';
use new_tr;
my $map = new_tr::getResult();
print Dumper( $map );
Вывод :
$VAR1 = {
'1' => {
'Albert' => 'Salesman',
'Smith' => 'Salesman',
'Brown' => 'Manager'
},
'2' => {
'Penfold' => 'Designer',
'Jurgens' => 'Manager',
'Evans' => 'Tea-person'
}
};