2011-11-07 43 views
6

Tôi đang cố gắng lấy mã C mã nội tuyến Ruby http://pastie.org/2825882 để hoạt động. Mã hoạt động trong vanilla C, nhưng ở đây tôi nhận được lỗi và cảnh báo. Điều gì gây ra lỗi này?Biên dịch mã Ruby Inline C - giải quyết lỗi

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

Ngoài ra, tại sao tôi nhận được lỗi sau?

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

Kiểm tra mã C kết quả (http://pastie.org/2826036) Tôi không thấy có gì sai với các đối số. Nhưng tôi cũng nhận được các cảnh báo sau:

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

Nó hơi say cài đặt ruby ​​của tôi trong khi thử nghiệm :) – RocketR

Trả lời

5

Bắt đầu với điều này:

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

Nếu bạn nhìn vào mã được tạo của bạn, chức năng backtrack được định nghĩa trên dòng 29:

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

Nó có bảy đối số, bản gốc sáu, cộng VALUE self vì nó đã được chuyển đổi thành một phương thức trên lớp Scan.

Các cuộc gọi đến chức năng này, trên dòng 67 trông như thế này:

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

Nó chỉ có sáu đối số. RubyInline không chuyển đổi điều này thành một cuộc gọi đến một phương thức trên đối tượng, nó chỉ đơn giản là sao chép nó đúng nguyên văn. Đây cũng là nơi các cảnh báo về makes integer from pointer without a cast đến từ: định nghĩa chức năng đã được chuyển đổi thành số VALUE giây, nhưng bạn đang gọi với các loại ban đầu.

Các thông báo lỗi nói rằng lỗi là từ dòng 73 trong backtrack_inline.rb vì chỉ thị trên dòng 54 của mã được tạo:

# line 61 "./backtrack_inline.rb" 

mà về cơ bản cho trình biên dịch để "thiết lập lại" dòng và tập giá trị của nó lỗi và xử lý dòng tiếp theo (55) là dòng 61 trong tệp ./backtrack_inline.rb. Dòng thực tế là 67, 12 trước 55, nhưng trình biên dịch báo cáo nó là 73, 12 trước 61 (giá trị được đặt lại thành) và từ một tệp differnt. Kỹ thuật này không thực sự làm việc trong trường hợp này vì nó không tính đến các dòng bổ sung được thêm bởi RubyInline. Dòng thực tế trong nguồn là 69.

Sửa lỗi đơn giản cho việc này là thay đổi định nghĩa của hàm backtrack thành hàm C chứ không phải thêm hàm đó làm phương thức trên đối tượng. Thay đổi builder.c thành builder.prefix (trên dòng 38 của tệp Ruby). Điều này sẽ không hoạt động nếu bạn muốn có backtrack sẵn có như một phương thức trên đối tượng trong Ruby. Nếu đó là trường hợp bạn có thể cần tạo một hàm khác làm phương thức, sau đó kết thúc hàm backtrack "thực".

Tiếp theo, nhìn vào

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

Điều này thực sự đề cập đến dòng 61 của mã được tạo, trông giống như:

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

StringValuePtr là một macro which is defined as:

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

này là nơi & trong lvalue required as unary '&' operand xuất phát từ. Bạn cần phải thêm một biến địa phương để được vế trái:

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

Trong trường hợp của tôi (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) hai sự thay đổi này đã chạy kịch bản mà không có lỗi , nhưng đã đưa ra cảnh báo:

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

Điều này thực sự đề cập đến dòng 46 của file ruby:

return (s - ss) - 1; 

ssschar *, tức là 64 bit pointe rs (trên máy này), và kiểu trả về của hàm là int - 32 bit. Thêm một diễn viên rõ ràng cố định này:

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

Nó bây giờ chạy sạch:

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

(Tôi hy vọng 14 là câu trả lời đúng!)

Dưới đây là một version of the script with these changes.

0

Ok ... suy nghĩ thêm một chút về điều này.

bạn đang gọi kết thúc biến. Trong khi đây không phải là một từ dành riêng trong C - và ruby ​​không nên nhìn vào nó ... có lẽ ruby ​​đang bối rối?

Tôi khuyên bạn nên đổi tên trong trường hợp đó. Đáng giá cố gắng thậm chí chỉ để loại trừ nó ra.

Các vấn đề liên quan