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燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP