27 votes

Pourquoi ne puis-je pas obtenir rasade envelopper std::vector de classe Ruby?

J'ai une application avec un intégré à l'interpréteur Ruby, et des interfaces pour la STL classes générées par gorgée. À peu près tout a bien marché grâce à swig, sauf pour une chose:

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

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

Lorsque j'essaie de l'utiliser dans Ruby le type Stuff::Vectord existe, mais il n'est pas le type de retour de la générées singleton méthode de test. En regardant le générés C fichier wrapper je peux voir la classe Vectord et ses méthodes définie, mais en regardant _wrap_test_get je ne vois rien de revenir sth de la classe Stuff::Vectord.

Que dois-je faire pour obtenir la test typé en tant que Vectord?

1voto

lefticus Points 1420

Tout d'abord, vous avez raison. Le rubis générés Stuff::test objet n'est pas de type Vectord.

Cependant, il est d'un type qui se comporte exactement comme Vectord qui est la question la plus importante pour un canard tapé langue comme le Rubis.

Correction de Trucs.j'

Il y a un problème mineur dans votre exemple. L' %import <stl_vector.i> déclaration doit être %include <stl_vector.i>.

Le bon exemple complet est:

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

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

La création d'un Module

La gorgée wrapper peut être générée avec

swig -ruby -c++ Stuff.i

Et compilé avec g++) avec l'énoncé:

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

En utilisant le Module

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

Comme nous pouvons le voir, l'objet retourné par Stuff::test est de type Array. Toutefois, contrairement à un régulière Ruby tableau, ce tableau ne peut être réglé à une valeur qui est convertible en un 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

Aussi, il peut être converti directement à partir des std::vector<double> objets.

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]

Autre GORGÉE Cibles

Il est important de noter que le typage statique RASADE cibles de C# et Java produire les résultats que vous attendiez. Si jamais vous avez une question à propos de comment vos types sont actuellement traitées dans le cadre d'une RASADE de sortie, il est presque toujours une bonne idée de comparer le C# ou Java, sortie à l'encontre de ce que vous attendez.

Conclusion

Alors qu' Stuff::test et Vectord sont de deux types différents, ils ont tous deux sont des tableaux qui ne peut stocker que de double.

Ils sont presque impossibles à distinguer à l'intérieur du code Ruby. Le code produit est exactement ce que vous voulez qu'il fasse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X