【问题标题】:Wrong arguments at ruby API in c-levelc 级 ruby​​ API 的错误参数
【发布时间】:2022-01-25 11:07:18
【问题描述】:

我使用 Ruby API 在 C 中创建了 ruby​​ 方法,它接收 3 个字符串参数:

VALUE cache_class = rb_define_class_under(class, CACHE_CLASS_NAME, rb_cObject);

rb_define_method(cache_class, "cache_test_result", cache_test_result, 3);

test.rb中我调用了方法:

Cache.new.cache_test_result("str1", "str2", "str3")

而 C cache_test_result 函数工作起来很奇怪:

VALUE cache_test_result(VALUE str1, VALUE str2, VALUE str3) {
   int rstr1_len = RSTRING_LEN(str1) + 1;
   char buf_str1[rstr1_len];
   strlcpy(buf_str1, RSTRING_PTR(str1), rstr1_len);

   int rstr2_len = RSTRING_LEN(str2) + 1;
   char buf_str2[rstr2_len];
   strlcpy(buf_str2, RSTRING_PTR(str2), rstr2_len);

   int rstr3_len = RSTRING_LEN(str3) + 1;
   char buf_str3[rstr3_len];
   strlcpy(buf_str3, RSTRING_PTR(str3), rstr3_len);

   printf("buf_str1: %s\n", buf_str1);
   printf("buf_str2: %s\n", buf_str2);
   printf("buf_str3: %s\n", buf_str3);
}
此函数的

输出

buf_str1: 
buf_str2: str1
buf_str3: str2

为什么 args 有偏移量...?

【问题讨论】:

    标签: c ruby


    【解决方案1】:

    To quote the documentation:

    C 函数的第一个参数是 self,其余的是方法的参数。

    这意味着你需要调整函数原型并添加一个额外的参数,例如:

    VALUE cache_test_result(VALUE self, VALUE str1, VALUE str2, VALUE str3) {
    

    因为VALUE 类型的 C 对象可以是所有东西(Ruby 字符串、整数或 nil),所以永远不要在不确定其 Ruby 类型的情况下使用RSTRING_{PTR,LEN} 和类似的(宏)函数。相反,您可以使用 Check_TypeStringValuePtrStringValueCStr,具体取决于用例。

    你的例子可以改写为:

    VALUE cache_test_result(VALUE self, VALUE str1, VALUE str2, VALUE str3) {
       // Check if each value is a Ruby string
       // (or can be implicitly converted to one) and
       // return a pointer to its underlying C string.
       // It it also checked if the Ruby string contains NUL.
       // If any check fails an exception is raised.
       const char *buf_str1 = StringValueCStr(str1);
       const char *buf_str2 = StringValueCStr(str2);
       const char *buf_str3 = StringValueCStr(str3);
       // print each underlying C string
       printf("buf_str1: %s\n", buf_str1);
       printf("buf_str2: %s\n", buf_str2);
       printf("buf_str3: %s\n", buf_str3);
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2021-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      相关资源
      最近更新 更多