Почему я не могу получить swig wrap std :: vector в классе Ruby? - PullRequest
28 голосов
/ 31 января 2011

У меня есть приложение со встроенным интерпретатором Ruby и интерфейсами к классам STL, сгенерированным swig.Благодаря Swig все в порядке, за исключением одного:

%module Stuff
%import "std_vector.i"
namespace std
{
  %template(Vectord) vector<double>;
}; 

%inline%{
  std::vector<double> test;
%}

Когда я пытаюсь использовать это в Ruby, тип Stuff::Vectord существует, но это не тип возвращаемого сгенерированного синглтона.метод испытания.Глядя на сгенерированный файл оболочки C, я вижу, как определяется класс Vectord и его методы, но, глядя на _wrap_test_get, я не вижу ничего, возвращающего sth класса Stuff::Vectord.

Что делатьЯ должен сделать, чтобы test набрал Vectord?

1 Ответ

2 голосов
/ 31 января 2012

Во-первых, вы правы. Сгенерированный в рубине объект Stuff::test не относится к типу Vectord.

Однако , он относится к типу, который ведет себя точно так же, как Vectord, что является наиболее важным вопросом для такого типа утки, как Ruby.

Исправление к Stuff.i

В вашем примере есть одна небольшая проблема. %import <stl_vector.i> оператор должен быть %include <stl_vector.i>.

Правильный завершенный пример:

%module Stuff
%include "std_vector.i"
namespace std
{
  %template(Vectord) vector<double>;
}; 

%inline%{
  std::vector<double> test;
%}

Сборка модуля

Обертку swig можно сгенерировать с помощью

swig -ruby -c++ Stuff.i

И скомпилирован (с g ++) с оператором:

g++ Stuff_wrap.cxx -shared -fPIC -o Stuff.so -I /usr/lib/ruby/1.8/x86_64-linux/

Использование модуля

jason@jason-VirtualBox:~$ irb
irb(main):001:0> require 'Stuff'
=> true
irb(main):003:0> Stuff::test.class
=> Array

Как мы видим, объект, возвращаемый Stuff::test, имеет тип Array. Однако, в отличие от обычного массива Ruby, этот массив может быть установлен только на значение, которое может быть преобразовано в std::vector<double>

irb(main):002:0> Stuff::test = [5,4,3]
=> [5, 4, 3]
irb(main):003:0> Stuff::test = [5.0, "5.0"]
TypeError: double
    from (irb):3:in `test='
    from (irb):3
    from :0

Кроме того, его можно преобразовывать напрямую в std::vector<double> объекты и из них.

irb(main):002:0> vec = Stuff::Vectord.new()
=> std::vector<double,std::allocator< double > > []
irb(main):003:0> vec << 5.0
=> 5.0
irb(main):004:0> vec << 2.3
=> 2.3
irb(main):005:0> vec
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):006:0> Stuff::test = vec
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):007:0> vec2 = Stuff::Vectord.new(Stuff::test)
=> std::vector<double,std::allocator< double > > [5.0,2.3]
irb(main):008:0> Stuff::test.class
=> Array
irb(main):009:0> vec2.class
=> Stuff::Vectord
irb(main):010:0> Stuff::test
=> [5.0, 2.3]

Другие цели SWIG

Важно отметить, что статически типизированные целевые объекты SWIG в C # и Java дают ожидаемые результаты. Если у вас когда-нибудь возникает вопрос о том, как обрабатываются ваши типы в выводе SWIG, почти всегда неплохо сравнить вывод C # или Java с тем, что вы ожидаете.

Заключение

Хотя Stuff::test и Vectord - это два разных типа, они оба являются массивами, которые могут хранить только двойные числа.

Они почти неразличимы внутри кода Ruby. Созданный код делает именно то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...