2013-12-19 72 views
0

我已經使用SWIG爲C++庫生成包裝,我將在ruby中使用它。是否有一種很好的通用方法來將swig生成的類封裝在ruby中?

由於它是一個C++庫,方法名稱不是「ruby like」,即它們是camelCase。我還需要添加一些我自己的方法,例如運營商。

所以我在想創建ruby類來包裝SWIG類,但是想保持簡單。這是我正在考慮的事情,除非有人能指出我更好的方向。

我創建了這個「方法包裝器」方法,我將使用它在新的ruby類中調用相應的swig生成方法。

我利用獲得通過

some_method = SomeClass.method(:some_method_name) 

方法的Ruby的方案,然後通過

some_method.call 

調用它以後是否有與該計劃的任何問題?

這裏是我的方法包裝方法:

def method_wrapper(target_method, hash_keys, args=[]) 
if args.length == 0 
    #puts "calling without args" 
    return_value = target_method.call 
else 
    if args[0].class == Hash 
     method_args = Array.new 
     hash_args = args[0] 
     hash_keys.each do |key| 
     arg_value = hash_args[key] 
     method_args << arg_value if arg_value 
     end 
     #puts "calling with hash args #{method_args}" 
     return_value = target_method.call(*method_args) 
    else 
     #puts "calling with args" 
     retrun_value = target_method.call(*args) 
    end 
    end 
    return return_value 
end 

,這裏是我會怎麼用它來包裹在夜風生成類的每個方法

class RubyClassName 
    def ruby_method_name(*args) 
    return method_wrapper(Swig_module_name::SwigClassName.method(:swigMethodName), [:ruby_hash_key_arg1, :ruby_hash_key_arg2], args) 
    end 
end 

然後我可以調用像這樣的方法

RubyClassName.ruby_method_name 
RubyClassName.ruby_method_name some_value 
RubyClassName.ruby_method_name(some_value1, some_value2) 
RubyClassName.ruby_method_name :ruby_hash_key_arg1 => some_value 
RubyClassName.ruby_method_name :ruby_hash_key_arg2 => some_value2, :ruby_hash_key_arg1 => some_value1 

回答

1

您可以使用%rename指令將C++類和函數重命名爲els e(例如,將FooBar重命名爲fooBar或foo_bar)。

你可以使用%extend來添加你自己的操作符等等。

我相信上面會支持你所有的調用示例,而不需要第二層包裝。

+0

我讀了關於重命名指令,我將不得不閱讀有關擴展。我曾經在這裏讀過,很多時候人們會創建這些包裝紅寶石類,即使它只是記錄api。您認爲最好避免添加額外的圖層? – nPn

+0

我贊成較少的圖層;錯誤的可能性較小。但是記錄導出的API肯定是有價值的; SWIG不支持,所以我一直看到API的出口商將用戶引用到C++文檔中,他們通常可以弄清楚如何使用它。但是如果你添加了很多你自己的方法,C++文檔將不夠用。你使用什麼文檔工具?在Python中,我們有sphinx,它可以很容易地在不編輯代碼的情況下編寫類。 – Schollii

+0

我使用重命名指令,它做了我想要的東西 – nPn

相關問題