如何将多维映射从c ++转换为perl中的哈希

问题描述 投票:2回答:1

我是Swig的新手,我正在尝试将c ++映射转换为Perl中的哈希。

存在一个使用c ++的Perl扩展,它需要返回多维数组或映射到Perl。我已经在swig接口文件中使用了模板,但是它提供了空结果。

swig接口文件:

%include "exception.i"
%exception {

    try {
        $action
        } catch (const std::exception &e) {

        SWIG_exception_fail(SWIG_RuntimeError, e.what());
        }
    }

%module new_tr
%{
/* Put headers and other declarations here */
#include "new_tr.h"
%}
%include <std_map.i>

%template(StringStringMap) std::map<int,  std::map<std::string,std::string>>;

%include "new_tr.h"

cpp文件

     std::map<int,  std::map<std::string,std::string>> Memberfunction::m;
    std::map<int,  std::map<std::string,std::string>> Memberfunction::getResult()
    {
        return m;
    }

perl文件

use strict;
use new_tr;
use Data::Dumper;

my $new=new new_tr::some();
print Dumper($new->getResult());

当前输出:

$VAR1 = bless( {}, 'new_tr::StringStringMap' );

预期输出:(多维哈希)

$VAR1 = bless( 0 =>    { 
                                'Brown' => 'Manager', 
                                'Smith' => 'Salesman', 
                                'Albert' => 'Salesman',  
                            },  
            1 =>  { 
                                'Penfold' => 'Designer', 
                                'Evans' => 'Tea-person', 
                                'Jurgens' => 'Manager',  
                            }, 'new_tr::StringStringMap' );
c++ perl swig
1个回答
1
投票

这里是如何将%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'
                 }
        };
© www.soinside.com 2019 - 2024. All rights reserved.