簡単な Ruby C 拡張機能を作成しました。メソッドは、2 番目のパラメーターが文字列風の VALUE であることを想定しています。
VALUE method_foo(VALUE self, VALUE key) {
puts(RSTRING(key)->ptr);
return key;
}
文字列ではなく整数を渡すと、非常に簡単にセグメンテーション違反が発生します。これをどのように検出し、C メソッドで防止または回復する必要がありますか?
簡単な Ruby C 拡張機能を作成しました。メソッドは、2 番目のパラメーターが文字列風の VALUE であることを想定しています。
VALUE method_foo(VALUE self, VALUE key) {
puts(RSTRING(key)->ptr);
return key;
}
文字列ではなく整数を渡すと、非常に簡単にセグメンテーション違反が発生します。これをどのように検出し、C メソッドで防止または回復する必要がありますか?
呼び出しCheck_Type (key, T_STRING)
(例外を発生させたい場合) または使用TYPE (key)
して手動でチェックすること (例外を発生させる以外のことをしたい場合)を検討する必要があります。
または、単純に がmethod_foo
文字列を期待していることを示し、呼び出し元に処理を任せることもできます。結局のところ、API は呼び出し元と呼び出し先の間の契約であり、呼び出し元が規則に違反した場合、それはクラッシュに対する完全に有効な応答です。
私は堅牢なソフトウェアを好むので、おそらくそうはしないでしょうが、人々は必ずしも自分の愚かさから保護されるべきではないという考え方があります。それは彼らが愚かであり続けることを奨励するだけです:-)
StringValuePtr(value) と StringValueCStr(value) は型チェックを行い、文字列ポインタを返します。私の知る限り、これらは C 拡張で Ruby 文字列から char* を抽出する方法として認められています。とりわけ (私が調べたときのことを覚えている限り)、どちらも戻り値が NULL でないことを確認し (場合によってはそうなる可能性があります)、StringValueCStr もそれが 0 で終わる文字列であることを確認します。Ruby 文字列はコピー オン ライトを使用するため、文字列のスライスが 0 で終了しない場合があります。