2012-08-14 86 views
2

我寫了一個簡單的Ruby C擴展。方法期望第二個參數是字符串值。Ruby C擴展,如何從分段錯誤中恢復

VALUE method_foo(VALUE self, VALUE key) { 

    puts(RSTRING(key)->ptr); 

    return key; 
} 

它很容易通過傳遞整數而不是字符串來引起分段錯誤。我應該如何檢測這一點,並防止或恢復C方法?

回答

4

你應該看看調用Check_Type (key, T_STRING)(如果你想提出一個例外),或使用TYPE (key)手動檢查(如果你想要做的事其他不是拋出一個異常)。

或者,您可以簡單地聲明method_foo需要一個字符串,並留給調用者處理。畢竟,您的API是調用者和被調用者之間的合同,如果調用者違反了規則,那麼這對於崩潰是非常有效的響應。

我可能不會這樣做,因爲我更喜歡強大的軟件,但有一種思想認爲人們不應該總是被保護免於自己的愚蠢。它只會鼓勵他們保持愚蠢:-)

+0

沒有,謝謝你的信息。我無法在http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html – 2012-08-14 02:48:36

+0

@Josh上列出其中的任何一個,它在「價值作爲指針」下面 - 也看看http:/ /clalance.blogspot.com.au/2011/01/writing-ruby-extensions-in-c-part-4.html – paxdiablo 2012-08-14 02:50:12

+0

你是對的API。我對某些「安全」的主要動機是讓它難以惡意破壞程序。雖然,這可能更好留給清理用戶輸入的Ruby層。 (因爲無論如何C函數都是關於速度的)。 – 2012-08-14 02:50:54

1

StringValuePtr(value)和StringValueCStr(value)進行類型檢查並返回字符串指針。 AFAIK,它們是從C擴展中的Ruby字符串中提取char *的公認方法。在一些事情中(據我所知,當我研究它時),它們都確保返回的值不是NULL(可能在某些情況下),並且StringValueCStr還確保它是以0結尾的字符串。由於Ruby字符串使用copy-on-write,所以字符串的一部分可能不會以0結尾。