首先,你是对的。 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 代码中几乎无法区分。生成的代码完全符合您的要求。