Ruby 板


LINE

http://www.swig.org/ SWIG is an interface compiler that connects programs written in C and C++ with scripting languages such as Perl, Python, Ruby, and Tcl. 也就是,让 C/C++ 与 scripting language 沟通的介面产生器 目前支援 13 种 scripting language: * Allegro Common Lisp * C# * Chicken * Guile * Java * Modula-3 * Mzscheme * OCAML * Perl * PHP * Python * Ruby * Tcl 之前我测了一些 Ruby 与 C++ 的沟通方式,以下将简单介绍一下测试的方法 首先先看到使用方式,我想这个应该是最重要的部份 毕竟如果使用不便,那其他的也不用再多说什麽了… (以下由於 BBS 之故,稍作排版修改) 以下这个程式是一个简单的 type wrapper,(传值版) 由 template parameter 指定型别, data() 当 getter, data(type) 当 setter. 另外在 c'tor 和 d'tor 中插入 IO 来追踪物件的生成与摧毁 // in Wrapper.h #include <iostream> template <class Data> class Wrapper{ public: Wrapper(Data new_data): data_(new_data){ std::cout << "C++: Wrapper is created, which is '" << data_ << "' .\n"; } ~Wrapper(){ std::cout << "C++: Wrapper is decayed, which is '" << data_ << "' .\n"; } Data data() const{ return data_; } void data(Data new_data){ data_ = new_data; } private: Data data_; }; 有了这个 .h 档的介面後(这里同时也包含实作), 接下来我们需要的是一个由 swig 产生的胶水,将 C++ 介面与 Ruby 介面混合 暂时命名为:Wrapper.i, 详细做法等一下我们再来看 总之最终我们将产生一个动态连结档,也就是一个 Ruby 的 module, 叫 Wrapper 不过需要一提的是,由於 Ruby 本身不支援 template, 所以我们在 Wrapper.i 中必须明确指出我们需要什麽型别, 否则 Ruby 会无法使用(更明确来讲,纯 template 根本无法 compile) 所以在 Wrapper.i 中,里面有一行是这个: %template(Integer) Wrapper<int>; 这句话的意思是,将 Wrapper<int> 这个型别取作 Integer 於是 Ruby module 做好後,可以使用 Integer 这个型别 虽然我中间还有很多测试,不过直接看目前的最後结果吧 写一个 Ruby 程式,内容如下: #!ruby # in test.rb require 'Wrapper' # 读入刚刚做好的 Wrapper module class Test < Wrapper::Integer # 继承 C++ 写好的 Wrapper<int> def initialize(new_data) # c'tor 其实可以省略,因为可以使用 super(new_data) # C++ 中写好的 Wrapper<int> end # 这里只是展示 super 是可以用的 def plus(num) data(data + num) data end end # 正式测试开始 fat = Test.new(123) # 建构出 Test 物件,传入 123 当引数 puts fat.plus(7) # output: 130 fat.data(456) # 设值为 456 puts fat.plus(4) # output: 460 ok, 可是原本插入 C++ 的 c'tor 中的 IO 呢? 整个程式的输出结果是这样: C++: Wrapper is created, which is '123' . 130 460 C++: Wrapper is decayed, which is '460' . 也就是说,C++ 的 c'tor 与 d'tor 有被确实唤起 这样说不定可以替 Ruby 实作出 d'tor...不过这是题外话 另外,刚刚程式中的 fat.data 与 fat.data(456) 确实是 唤起正确的 getter 与 setter, 可是 Ruby 没有 overload? 我没有实际去看,但我猜他内部大概是这样实作的: def data(*args) case args.size when 0 then return self.data_a when 1 then return self.data_b(args[0]) end end 所以如果你想要重新定义其中一个 overloaded method, 做不到… 可能必须找到他实际的名字才有办法 那麽我们再来看到由 C++ 呼唤 Ruby... 否则不就太寂寞了吗? 基本上 Ruby 本身就提供了良好与 C 沟通的机制,照用不就好了? 是这样说没错,可是说真的我很讨厌 C 的介面…囧rz 常常会要你记下一堆有的没的,感觉很讨厌 所以我觉得需要一个 C++ 的 wrapper, 一个可以轻松呼叫 Ruby 的方式 像上面推文中所提到的,我找到这个: http://www.sourcepole.com/sources/software/c++ruby/ 不过这个东西实在是写得不好,没有处理 finalize 的部份 不知道还有没有其他类似的 wrapper 可以用,所以我就暂时用这个来改 改写他 singleton 的实作,还有记得在 d'tor 中呼叫 ruby_finalize(); 最後的结果是,我可以这样写: #include "rubyeval.h" // 就是上面抓来的那个 #include <ruby.h> // embedded ruby 必要的东西,去 ruby-lang 就可以抓 int main(){ RubyEval& ruby = RubyEval::instance(); ruby.eval("require 'Wrapper'"); // 直接用字串执行 Ruby // 这边是含入刚刚做好的 C++ => Ruby mod // 当然这东西要先 compile 好 ruby.eval("fat = Wrapper::Integer.new(123)"); // 直接建立物件 std::cout << NUM2INT(ruby.eval("fat.data")) << std::endl; // 输出 123 ruby.eval("fat.data(456);"); // 设值 456 std::cout << NUM2INT(ruby.eval("fat.data")) << std::endl; // 输出 456 ruby.run_file("test.rb"); // 直接执行 ruby 程式 } 那个 test.rb, 就是上面写好拿来测试 Ruby 呼叫 C++ 的程式 於是整个输出结果就是: C++: Wrapper is created, which is '123' . 123 456 C++: Wrapper is created, which is '123' . 130 460 C++: Wrapper is decayed, which is '460' . C++: Wrapper is decayed, which is '456' . 第一行是从 C++ 建构的 Integer; 123, 456 则是 cout 输出的 第四行的 123 则是 test.rb 产生 class Test < Wrapper::Integer 那个 130, 460 则是 Ruby 的 puts 产生出来的 最後两个 decayed 则是 Ruby 的 gc 正确在程式结束时摧毁物件输出的 顺序刚好跟 c'tor 反过来,一切正常 最後就来看怎麽实现这个的 Wrapper.i 是这样写的: %module Wrapper %{ #include "Wrapper.h" %} %include "Wrapper.h" %template(Integer) Wrapper<int>; 这些语法请参考 SWIG 的网站,那边都有详细说明 甚至是 C++ 的多重继承,在 Ruby 中也能使用 当然多少可能会有点限制,但似乎可以实现一定的功能 下指令: swig -c++ -ruby Wrapper.i 这样就可以以 Wrapper.i 这个介面档实作出由 Ruby 沟通 C++ 的程式 那个程式会叫做 Wrapper_wrap.cxx, 也就是 YOUR_NAME_wrap.cxx 再来就是将所有的程式打包成一个动态连结档了,所有的档案是: Wrapper.h (包含实作), Wrapper_wrap.cxx (SWIG 的胶水) 方便的做法是使用 Ruby 的 mod, 叫 mkmf 写一个 Ruby 程式叫 mkmf.rb, 内容是: require 'mkmf' $libs = append_library($libs, "stdc++") create_makefile(ARGV[0]) 这边是由於我个人方便,所以这样写的 第一行含入 mkmf, 第二行是因为我用到 C++ 标准函数库(cout), 所以必须连结 stdc++ 才行(我的系统是 gcc, VC++ 的话我不清楚) 接着由 create_makefile 产生出我要的 makefile, 名称由 cmd line 输入 这边我是输入 Wrapper (btw, 有人知道 stdc++ 可否动态连结吗?) 接着就可以由 make 将 Wrapper.h 和 Wrapper_wrap.cxx 合并做出 Wrapper.so (我想 VC++ 系统应该会做出 Wrapper.dll 之类的) 最後要提的是,整个程式的执行环境 由於我是在 cygwin 下作业的,所以独立执行这些程式需要的是: cygwin1.dll 1.78 MB cygruby18.dll 703 KB cygcrypt-0.dll 6.5 KB 我想如果在 windows 下由 VC++ compile 的话, 应该就只会需要 Ruby interpreter 的 dll 档(这里是 cygruby18.dll) 不过我就没有做这一步的测试了,留给读者当作练习吧 XD (忽然心血来潮所以整理了这些东西) -- Nobody can take anything away from him. Nor can anyone give anything to him. What came from the sea, has returned to the sea. Chrono Cross --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18
1F:推 dotZu:13种语言怎麽有Java但没Java Script 08/06 18:53
2F:→ godfat:Java 和 JavaScript 没有因果关系 08/06 19:02
3F:→ SBT:Java 和 JavaScript 完全不一样 08/06 22:43
4F:推 PsMonkey:ㄟㄟ... 把那些 html 还有论坛的 tag 去掉好呗... 08/07 22:22
5F:→ godfat:其实那是我在这里打时打上去的 XD 另一种颜文字吧 @_@ 08/07 23:21
※ 编辑: godfat 来自: 220.135.28.18 (08/07 23:25)
6F:推 dotZu:二、三楼:正是因为不一样才奇怪啊 Java 不是 Scripting 08/08 13:30
7F:推 cplusplus:反正只是想要利用C\C++的效率吧? 那JAVA也可以用啊~ 08/08 14:14
8F:→ cplusplus:又话说JAVASCRIPT一般在BROWSER上执行 比较少会去用这个 08/08 14:14
9F:→ cplusplus:编好的MODULE吧...? 08/08 14:16







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP