swig perl typemap (out) std :: vectorне возвращает желаемый результат в Perl - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь набрать карту типов (out) std :: vector.Я хочу, чтобы он получил код Perl в виде массива, вместо этого я получаю массив массивов, который после двойной разыменования содержит нужные данные.как я могу сделать это массивом строк в Perl?

Я пытался редактировать карту типов самостоятельно и использовать карты типов в std_vector.i и std_string.i без редактирования, и все онивыдайте те же результаты.

это код карты типов:

%typemap(out) std::vector<std::string> {
        int len = $1.size();
        SV *svs = new SV[len];
        for (int x = 0; x < len; x++) {
                SV* sv = sv_newmortal();
                sv_setpvn(sv, $1[x].data(), $1[x].size());
                svs[x] = SvPV(sv, $1[x].size());
        }
        AV *myav = av_make(len, svs);
        delete[] svs;
        $result = newRV_noinc((SV*) myav);
        sv_2mortal($result);
        argvi++;
} 

мой код для проверки вывода:

#this return a std vector<string> in the cpp code
my @commitReturn = $SomeClass->commit();
        print "\n";
        #this should return a string instead it returns an array.
        print $commitReturn[0];
        print "\n";
        #this should not work, instead it returns the desired output.
        print $commitReturn[0][0];

вывод:

ARRAY(0x908c88)
20790

вместо:

20790
Can't use string ("20791") as an ARRAY ref while "strict refs"

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Чтобы вернуть массив вместо ссылки на массив, вы должны манипулировать стеком так, чтобы Perl знал, что возвращается более одного скаляра.

Согласно документации :

Текущее значение указателя стека аргументов содержится в переменной argvi.Всякий раз, когда добавляется новое выходное значение, очень важно, чтобы это значение увеличивалось.Для нескольких выходных значений конечное значение argvi должно быть общим числом выходных значений.

Таким образом, должно быть достаточно следующей карты типов:

%typemap(out) std::vector<std::string> {
    int len = $1.size();
    for (int x = 0; x < len; x++) {
        $result = sv_newmortal();
        sv_setpvn($result, $1[x].data(), $1[x].size());
        argvi++;
    }
} 
0 голосов
/ 24 января 2019

Ваш commit метод просто возвращает ссылку на массив, а не массив ссылок на массив.Может быть, это похоже на массив ссылок на массив, потому что вы присваиваете результат массиву?

В любом случае, не касаясь кода карты типов, вы можете разыменовать вызов функции

@commitReturn = @{$SomeClass->commit()};

или создайте метод-обертку, чтобы разыменовать его для вас

package SomeClass;
...
sub commit_list {
    my $self = shift;
    @{$self->commit()};
}
...
@commitReturn = $SomeClass->commit_list();
...