如何在perl中将多维Map从c++转换为hash

ubof19bj  于 2023-01-05  发布在  Perl
关注(0)|答案(1)|浏览(163)

我是swig的新手,我正在尝试用Perl将c++ map转换为散列。
有一个使用C++的Perl扩展需要返回一个多维数组或Map到Perl。我已经在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' );
nbnkbykc

nbnkbykc1#

下面是一个示例,说明如何将%typemap用于嵌套的std::map

    • 新的交易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"
    • 新_交易. h**:
#include <map>
#include <string>
using ssmap = std::map<int,  std::map<std::string,std::string>>;
ssmap getResult();
    • 新的交易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'
                 }
        };

相关问题