我正在尝试从 C 代码调用 ruby 正则表达式:
`
#包括
int main(int argc, char** argv) {
char string[] = "regex";
ruby_setup();
rb_reg_regcomp(string);
return 0;
} ` 我自己编译了最新版本的 ruby(提交 0b303c683007598a31f2cda3d512d981b278f8bd)并将我的程序链接到它。它在警告下编译得很好:
fuzzer.c: In function ‘main’: fuzzer.c:10:17: warning: passing argument 1 of ‘rb_reg_regcomp’ makes integer from pointer without a cast [-Wint-conversion] 10 | rb_reg_regcomp(string); | ^~~~~~ | | | char * In file included from fuzzer.c:4: /home/cyberhacker/Asioita/Hakkerointi/Rubyregex/ruby/build/output/include/ruby-3.3.0+0/ruby/re.h:36:28: note: expected ‘VALUE’ {aka ‘long unsigned int’} but argument is of type ‘char *’ 36 | VALUE rb_reg_regcomp(VALUE str);
我认为是因为 ruby 源代码中的“VALUE”关键字是指向任何类型的通用指针。当我尝试运行该程序时,我遇到了这个回溯的段错误:
Program received signal SIGSEGV, Segmentation fault. rb_enc_dummy_p (enc=enc@entry=0x0) at ../encoding.c:181 181 return ENC_DUMMY_P(enc) != 0; (gdb) where #0 rb_enc_dummy_p (enc=enc@entry=0x0) at ../encoding.c:181 #1 0x000055555569bd00 in rb_reg_initialize (obj=obj@entry=140737345038080, s=0xc62000007ffff78a <error: Cannot access memory at address 0xc62000007ffff78a>, len=-4574812796478291968, enc=enc@entry=0x0, options=options@entry=0, err=err@entry=0x7fffffffdb30 "", sourcefile=0x0, sourceline=0) at ../re.c:3198 #2 0x00005555556a11c8 in rb_reg_initialize_str (sourceline=0, sourcefile=0x0, err=0x7fffffffdb30 "", options=0, str=140737488346082, obj=140737345038080) at ../include/ruby/internal/core/rstring.h:516 #3 rb_reg_init_str (options=0, s=140737488346082, re=140737345038080) at ../re.c:3299 #4 rb_reg_new_str (options=0, s=140737488346082) at ../re.c:3291 #5 rb_reg_regcomp (str=140737488346082) at ../re.c:3373 #6 0x0000555555584648 in main () at ../include/ruby/internal/encoding/encoding.h:418
我试图摆弄我传递给函数的字符串的类型,但似乎没有任何效果。预期的行为是它成功运行。
有人可以帮忙吗?提前致谢!
经过一番挖掘,我发现您需要将 c 字符串转换为 ruby 字符串,然后将其传递给函数。我很困惑,因为在文档中他们说:“Ruby 的 String 有点对应于 C 的 char*。” .
#include <ruby.h>
#include "ruby/re.h"
int main(int argc, char** argv) {
VALUE x;
char string[] = "regex";
x = rb_str_new_cstr(string);
rb_reg_regcomp(x);
return 0;
}