gpt4 book ai didi

ruby - 为什么我不能让 swig wrap std::vector 到 Ruby 类?

转载 作者:数据小太阳 更新时间:2023-10-29 06:26:58 26 4
gpt4 key购买 nike

我有一个带有嵌入式 Ruby 解释器的应用程序,以及与 swig 生成的 STL 类的接口(interface)。多亏了 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 我没有看到任何返回 sthStuff::Vectord

我需要做什么才能将 test 键入为 Vectord

最佳答案

首先,你是对的。 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::testVectord是两种不同的类型,它们都是只能存储double的数组。

它们在 Ruby 代码中几乎无法区分。生成的代码完全符合您的要求。

关于ruby - 为什么我不能让 swig wrap std::vector 到 Ruby 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4849633/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com