首先,你是正确的。Ruby生成的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 目标
需要注意的是,C# 和 Java 这两个静态类型的 SWIG 目标产生了您所期望的结果。如果您对 SWIG 的输出如何处理您的类型有任何疑问,将 C# 或 Java 输出与您所期望的进行比较几乎总是一个好主意。
结论
虽然 Stuff::test
和 Vectord
是两种不同的类型,但它们都是只能存储双精度浮点数的数组。
在 Ruby 代码中,它们几乎无法区分。生成的代码完全按照您的要求执行。