我有一个带有嵌入式Ruby解释器的应用程序,以及与swig生成的STL类的接口。 几乎所有的事情都很好,这要归功于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
?
答案 0 :(得分:2)
首先,你是对的。 ruby生成的Stuff::test
对象不属于Vectord
类型。
然而,它的行为与Vectord
完全相同,这是像Ruby这样的鸭子类型语言最重要的问题。
您的示例中存在一个小问题。 %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]
值得注意的是,C#和Java的静态类型SWIG目标会产生您期望的结果。如果您对如何在SWIG输出中处理类型有疑问,那么将C#或Java输出与您期望的内容进行比较几乎总是一个好主意。
虽然Stuff::test
和Vectord
是两种不同的类型,但它们都是只能存储双打的数组。
它们在Ruby代码中几乎无法区分。生成的代码完全符合您的要求。