Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

183
Vistas
Wrong arguments at ruby API in c-level

I created ruby method in C using Ruby API which receive 3 string arguments:

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);

In test.rb I called method:

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

And C cache_test_result function works strange:

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);
}

output of this function:

buf_str1: 
buf_str2: str1
buf_str3: str2

why args has offset...?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

To quote the documentation:

The first argument of the C function is the self, the rest are the arguments to the method.

Which means you need to adjust the function prototype and add an additional parameter, e.g.:

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

And since a C object of type VALUE can be everything (a Ruby string, integer or nil) never use RSTRING_{PTR,LEN} and similar (macro) functions without being sure of its Ruby type. Instead you may use Check_Type, StringValuePtr, or StringValueCStr depending on the use case.

Your example could be rewritten as:

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);
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda