29 Stimmen

Warum kann ich nicht swig wrap std::vector zu Ruby-Klasse?

Ich habe eine Anwendung mit einem eingebetteten Ruby-Interpreter und Schnittstellen zu STL-Klassen von Swig generiert. So ziemlich alles hat dank Swig gut funktioniert, außer einer Sache:

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

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

Wenn ich versuche, dies in Ruby zu verwenden, wird der Typ Stuff::Vectord existiert, aber es ist nicht der Rückgabetyp der generierten Singleton-Methode test. Wenn ich mir die generierte C-Wrapper-Datei ansehe, sehe ich die Klasse Vectord und ihre Methoden werden definiert, aber wenn man sich _wrap_test_get Ich sehe keine Rückkehr sth der Klasse Stuff::Vectord .

Was muss ich tun, um test getippt als Vectord ?

2 Stimmen

Ich habe mit Ihrem Beispiel gearbeitet und ich sehe kein Problem bei der Erzeugung von Ruby- oder C#-Ausgaben. Es stimmt, dass Sie keinen speziellen Vectord-Typ in der von Swig generierten Ausgabe für die test()-Funktion sehen, aber sie gibt den richtigen Typ zurück. Ich habe gelernt, dass ein Test mit C# und die Erkundung der in den *.cs-Wrappern verwendeten Typen ein guter Sanity-Check für Ihren SWIG-Code sein kann.

3voto

lefticus Punkte 3268

Erstens: Sie haben Recht. Das von Ruby erzeugte Stuff::test Objekt ist nicht vom Typ Vectord .

Allerdings ist sie von einem Typ, der sich genauso verhält wie Vectord was die wichtigste Frage für eine ententypisierte Sprache wie Ruby ist.

Berichtigung von Stuff.i

In Ihrem Beispiel gibt es ein kleines Problem. Die %import <stl_vector.i> Anweisung sollte sein %include <stl_vector.i> .

Das richtige vollständige Beispiel lautet:

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

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

Aufbau des Moduls

Der Swig-Wrapper kann erzeugt werden mit

swig -ruby -c++ Stuff.i

Und kompiliert (mit g++) mit der Anweisung:

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

Verwendung des Moduls

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

Wie wir sehen können, ist das Objekt, das von Stuff::test ist vom Typ Array . Im Gegensatz zu einem normalen Ruby-Array kann dieses Array jedoch nur auf einen Wert gesetzt werden, der in einen 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

Außerdem kann es direkt in und aus std::vector<double> Objekte.

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]

Andere SWIG-Ziele

Es ist wichtig zu wissen, dass die statisch typisierten SWIG-Ziele von C# und Java die erwarteten Ergebnisse liefern. Wenn Sie jemals eine Frage dazu haben, wie Ihre Typen in einer SWIG-Ausgabe behandelt werden, ist es fast immer eine gute Idee, die C#- oder Java-Ausgabe mit dem zu vergleichen, was Sie erwarten.

Schlussfolgerung

Während Stuff::test y Vectord sind zwei verschiedene Typen, beide sind Arrays, die nur Doubles speichern können.

Sie sind innerhalb des Ruby-Codes fast nicht zu unterscheiden. Der erzeugte Code tut genau das, was Sie wollen.

0 Stimmen

Sie sagten, Sie hätten %import in %include geändert, aber das "korrekte vollständige Beispiel" zeigt immer noch "%import". War das ein Versehen?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X