2011-11-07 20 views
6

Próbuję uruchomić ten kod napisany w Rubi w języku C http://pastie.org/2825882. Kod działa w wanilii C, ale tutaj dostaję błędy i ostrzeżenia. Co powoduje ten błąd?Kompilowanie kodu Ruby Inline C - rozwiązywanie błędów

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

Ponadto, dlaczego pojawia się następujący błąd?

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

Kontrola wynikowy kod C (http://pastie.org/2826036) Nie widzę nic złego z argumentami. Ale dostaję również następujące ostrzeżenia:

./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

ona przykręcona moją instalację rubinowy podczas eksperymentowania :) – RocketR

Odpowiedz

5

Wychodząc z tego:

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

Jeśli spojrzeć na wygenerowanego kodu, funkcja backtrack jest zdefiniowana w wierszu 29:

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

Ma siedem argumentów, oryginalny sześć plus VALUE self ponieważ został przekształcony w metodę na klasie Scan.

Wywołanie tej funkcji, na linii 67 wygląda następująco:

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

Ma tylko sześć argumentów. RubyInline nie konwertuje tego na wywołanie metody na obiekcie, po prostu kopiuje je dosłownie. Tutaj również pochodzą ostrzeżenia o makes integer from pointer without a cast: definicja funkcji została przekształcona, aby uzyskać VALUE s, ale dzwonisz z oryginalnymi typami.

Komunikat o błędzie mówi, że błąd jest z linii 73 w backtrack_inline.rb powodu dyrektywy w sprawie linii 54 wygenerowanego kodu:

# line 61 "./backtrack_inline.rb" 

które zasadniczo mówi, że kompilator „Reset” swoje wartości linii i plików dla błędów i traktują następny wiersz (55) jako wiersz 61 w pliku ./backtrack_inline.rb. Rzeczywista linia to 67, 12 przed 55, ale kompilator zgłasza to jako 73, 12 przed 61 (wartość, do której został zresetowany) oraz z innego pliku. Ta technika nie działa w tym przypadku, ponieważ nie uwzględnia dodatkowych linii dodanych przez RubyInline. Rzeczywista linia w źródle to 69.

Prostą poprawką jest zmiana definicji funkcji backtrack jako tylko funkcji C, zamiast dodawania jej jako metody do obiektu. Zmień builder.c na builder.prefix (w linii 38 twojego pliku Ruby). To nie zadziała, jeśli chcesz mieć dostęp do backtrack jako metody na obiekcie w Ruby. W takim przypadku możesz potrzebować stworzyć inną funkcję, która będzie łączyć się z "prawdziwą" funkcją backtrack.

Następnie, patrząc na

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

To rzeczywiście odnosi się do linii 61 wygenerowanego kodu, który wygląda tak:

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

StringValuePtr jest macro which is defined as:

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

ten jest gdzie & w lvalue required as unary '&' operand pochodzi z. Trzeba dodać zmienną lokalną być lwartość:

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

W moim przypadku (Mac OS X Snow Leopard, Ruby 1.9.3-P0, RubyInline 3.11.0) te dwie zmiany dokonane przebieg skryptu bez błędów , ale dał ostrzeżenie:

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

To rzeczywiście odnosi się do linii 46 pliku ruby ​​

return (s - ss) - 1; 

s i sschar *, czyli 64 bit pointe rs (na tym komputerze), a typem zwrotu funkcji jest int - 32 bity. Dodanie wyraźnego stałej obsady to:

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

To teraz prowadzi czysto:

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

(mam nadzieję, że 14 jest poprawna odpowiedź!)

Oto version of the script with these changes.

0

Ok ... trochę więcej o tym pomyślałem.

Wywołujesz zmienny koniec. Chociaż nie jest to słowo zastrzeżone w języku C - a rubin nie powinien na nie patrzeć ... być może ruby ​​jest zdezorientowany?

Proponuję, abyś zmienił nazwę na wszelki wypadek. Warto próbować nawet po to, aby to wykluczyć.