2011-11-07 12 views
6

Estoy tratando de obtener este código Ruby inline C http://pastie.org/2825882 para que funcione. El código funciona en vainilla C, pero aquí recibo errores y advertencias. ¿Qué causa este error?Compilando el código Ruby Inline C - resuelve los errores

./backtrack_inline.rb:67: error: lvalue required as unary '&' operand 

Además, ¿por qué aparece el siguiente error?

./backtrack_inline.rb:73: error: too few arguments to function 'backtrack' 

Inspeccionar el código C resultante (http://pastie.org/2826036) No veo nada malo en los argumentos. Pero también recibo las siguientes advertencias:

./backtrack_inline.rb:73: warning: passing argument 1 of 'backtrack' makes integer from pointer without a cast 
./backtrack_inline.rb:73: warning: passing argument 2 of 'backtrack' makes integer from pointer without a cast 
./backtrack_inline.rb:73: warning: passing argument 3 of 'backtrack' makes integer from pointer without a cast 
+0

Se atornilla mi instalación de rubí mientras que la experimentación :) – RocketR

Respuesta

5

A partir de esto:

./backtrack_inline.rb:73: error: too few arguments to function 'backtrack' 

Si nos fijamos en el código generado, la función backtrack se define en la línea 29:

static VALUE backtrack(VALUE self, VALUE _ss, VALUE _s, VALUE _p, VALUE _mm, VALUE _ins, VALUE _del) { ... } 

Tiene siete argumentos, los seis originales, además de VALUE self como se ha convertido en un método en la clase Scan.

La llamada a esta función, en la línea 67 se parece a esto:

end = backtrack(ss, s, p, mm, ins, del); 

Tiene sólo seis argumentos. RubyInline no convierte esto en una llamada a un método en el objeto, simplemente lo copia al pie de la letra. Aquí es también donde provienen las advertencias sobre makes integer from pointer without a cast: la definición de la función se ha convertido para tomar VALUE s, pero está llamando con los tipos originales.

El mensaje de error dice que el error es de la línea 73 en backtrack_inline.rb debido a la directiva sobre la línea 54 del código generado:

# line 61 "./backtrack_inline.rb" 

que básicamente le dice al compilador de "reiniciar" sus valores de la línea y del archivo para errores, y trate la línea siguiente (55) como la línea 61 en el archivo ./backtrack_inline.rb. La línea real es 67, 12 delante de 55, pero el compilador informa que es 73, 12 delante de 61 (el valor al que se restableció) y de un archivo diferente. Esta técnica realmente no funciona en este caso, ya que no tiene en cuenta las líneas adicionales añadidas por RubyInline. La línea real en la fuente es 69.

Una solución simple para esto es cambiar la definición de la función backtrack para que sea solo una función C en lugar de agregarla como método en el objeto. Cambie builder.c a builder.prefix (en la línea 38 de su archivo Ruby). Esto no funcionará si desea tener backtrack disponible como método en el objeto en Ruby. Si ese es el caso, es posible que necesite crear otra función para que sea el método, que luego envuelve la función de retroceso "real".

A continuación, mirando

./backtrack_inline.rb:67: error: lvalue required as unary '&' operand 

En realidad, esto se refiere a la línea 61 del código generado, que se parece:

char* s = StringValuePtr(rb_iv_get(self, "@seq")); 

StringValuePtr es una macro which is defined as:

#define StringValue(v) rb_string_value(&(v)) 

Este es donde el & en lvalue required as unary '&' operand viene de. Es necesario añadir una variable local a ser el valor izquierdo:

VALUE seq = rb_iv_get(self, "@seq"); 
char* s = StringValuePtr(seq); 

En mi caso (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) estos dos cambios hizo la secuencia de comandos ejecutada sin errores , pero dio la advertencia:

backtrack_inline.rb:47: warning: implicit conversion shortens 64-bit value into a 32-bit value 

en realidad, esto se refiere a la línea 46 del fichero rubí:

return (s - ss) - 1; 

s y ss son char *, es decir Pointe 64 bit rs (en esta máquina), y el tipo de retorno de la función es int - 32 bits. La adición de una conversión explícita fijo esto:

return (int)((s - ss) - 1); 

Ahora se instala y ejecuta:

ruby-inline $ ruby backtrack_inline.rb 
14 
ruby-inline $ 

(espero 14 es la respuesta correcta!)

Aquí hay una version of the script with these changes.

0

Ok ... pensé un poco más acerca de esto.

está llamando a un final variable. Si bien esta no es una palabra reservada en C, y Ruby no debería mirarla ... ¿quizás el rubí se está confundiendo?

Le sugiero que intente cambiar el nombre por si acaso. Vale la pena intentarlo incluso para descartarlo.

Cuestiones relacionadas