stillflame
Programmer
- Jan 12, 2001
- 416
hey all,
this is likely well beyond the scope of what any of you have done with ruby, but i figured i'd ask it here, and at least answer it myself when and if i figure it out.
i have a problem writing this ruby extension 'o mine, and i was wondering if anyone could help me figure out why. i've narrowed it down to me not knowing enough about how ruby is wrapping structures, and how i have to treat those objects. for starters, i'm not really a wiz in c - this may be more at the root of my problem than anything else. my current guesses point to somewhere in the memory allocation area or in the Data_(Get|Wrap)_Struct calls, but i don't really know.
anyway, here's a piece of my c coding that should (hopefully) show where i'm having the problem. nothing in it will really be important except the "Data_(Wrap|Get)_Struct" parts and what they deal with, as the rest i have verified as functional with non-ruby-extending test programs that use the same fuctions (but i left it in to help describe the setting):
#################### C code starts here [tt]
VALUE cDictionary;
static void LP_dict_delete(void *p)
{
Dictionary *q;
q = p;
dictionary_delete(*q);
/* int dictionary_delete(Dictionary) */
}
VALUE LP_dict_new(VALUE class, VALUE dict_names)
{
VALUE rb_dict;
VALUE argv[1];
Dictionary *LP_dict;
*LP_dict = dictionary_create(
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)));
argv[0] = rb_dict = Data_Wrap_Struct(class, 0, LP_dict_delete, LP_dict);
rb_obj_call_init(rb_dict, 1, argv);
return rb_dict;
}
static VALUE LP_dict_init(VALUE self, VALUE dict_names)
{
rb_iv_set(self, "@dict_names", dict_names);
return self;
}
static VALUE LP_dict_get_max_cost(VALUE self)
{
Dictionary *LP_dict;
int cost;
Data_Get_Struct(self, Dictionary, LP_dict);
cost = dictionary_get_max_cost(*LP_dict);
return INT2NUM(cost);
}
[/tt]
## then later, in the Init subroutine, this is the relevant part: [tt]
cDictionary = rb_define_class_under(mLinkParsing, "Dictionary", rb_cObject);
rb_define_singleton_method(cDictionary, "new", LP_dict_new, 1);
rb_define_method(cDictionary, "initialize", LP_dict_init, 1);
rb_define_method(cDictionary, "get_max_cost", LP_dict_get_max_cost, 0);
[/tt]
#################### C code ends here
in the test script:
----------------------------- [tt]
#'require's and stuff...
dict = Dictionary.new(dict_names)
dict.get_max_cost()
test.rb:20: [BUG] Segmentation fault
ruby 1.7.0 (2001-05-17) [i686-linux]
Aborted [/tt]
-----------------------------
and also:
----------------------------- [tt]
dict = Dictionary.new(dict_names)
dict = nil
GC.start
test.rb:21: [bug] rb_gc_mark(): unknown data type 0x28(0x4034b690) corrupted object
ruby 1.7.0 (2001-05-17) [i686-linux]
Aborted [/tt]
-----------------------------
i know - ruby version 1.7.0, but i tried it with 1.6.3 to the same effect, so that's not an issue. for the most part, this seems to have the same structure as the example that Dave and /\ndy give in their book (p. 181), but, well i don't know - if i knew how to debug c stuff better, i could probly figure this out on my own, but, as it is, i've hit a dead end as to how i should attack this problem. i've tried pre-ALLOC-ing the Dictionary struct, but dictionary_create does that for itself:
--------------------------------------- [tt]
static Dictionary internal_dictionary_create(char * dict_name, char * pp_name, char * cons_name, char * affix_name, char * path) {
Dictionary dict;
static int rand_table_inited=FALSE;
Dict_node *dict_node;
char * dictionary_path_name;
dict = (Dictionary) xalloc(sizeof(struct Dictionary_s));
/* then fills that structure */ [/tt]
---------------------------------------
(note: in addition to 'xalloc', the program i'm wrapping also defines and uses an 'xfree'. this matters only because ruby.h has a macro that redefines 'xfree' to 'ruby_xfree' - i get errors unless i include the program's files before ruby's.)
there's lots of other things i've tried, in fact i've came up with a few more ideas while writing this letter, but (...time passes) to no avail. all i think i'm asking for is suggestions on where i should look to solve this.
thank you, anyone who takes the time to consider this,
stillflame "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."
this is likely well beyond the scope of what any of you have done with ruby, but i figured i'd ask it here, and at least answer it myself when and if i figure it out.
i have a problem writing this ruby extension 'o mine, and i was wondering if anyone could help me figure out why. i've narrowed it down to me not knowing enough about how ruby is wrapping structures, and how i have to treat those objects. for starters, i'm not really a wiz in c - this may be more at the root of my problem than anything else. my current guesses point to somewhere in the memory allocation area or in the Data_(Get|Wrap)_Struct calls, but i don't really know.
anyway, here's a piece of my c coding that should (hopefully) show where i'm having the problem. nothing in it will really be important except the "Data_(Wrap|Get)_Struct" parts and what they deal with, as the rest i have verified as functional with non-ruby-extending test programs that use the same fuctions (but i left it in to help describe the setting):
#################### C code starts here [tt]
VALUE cDictionary;
static void LP_dict_delete(void *p)
{
Dictionary *q;
q = p;
dictionary_delete(*q);
/* int dictionary_delete(Dictionary) */
}
VALUE LP_dict_new(VALUE class, VALUE dict_names)
{
VALUE rb_dict;
VALUE argv[1];
Dictionary *LP_dict;
*LP_dict = dictionary_create(
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)),
STR2CSTR(rb_ary_shift(dict_names)));
argv[0] = rb_dict = Data_Wrap_Struct(class, 0, LP_dict_delete, LP_dict);
rb_obj_call_init(rb_dict, 1, argv);
return rb_dict;
}
static VALUE LP_dict_init(VALUE self, VALUE dict_names)
{
rb_iv_set(self, "@dict_names", dict_names);
return self;
}
static VALUE LP_dict_get_max_cost(VALUE self)
{
Dictionary *LP_dict;
int cost;
Data_Get_Struct(self, Dictionary, LP_dict);
cost = dictionary_get_max_cost(*LP_dict);
return INT2NUM(cost);
}
[/tt]
## then later, in the Init subroutine, this is the relevant part: [tt]
cDictionary = rb_define_class_under(mLinkParsing, "Dictionary", rb_cObject);
rb_define_singleton_method(cDictionary, "new", LP_dict_new, 1);
rb_define_method(cDictionary, "initialize", LP_dict_init, 1);
rb_define_method(cDictionary, "get_max_cost", LP_dict_get_max_cost, 0);
[/tt]
#################### C code ends here
in the test script:
----------------------------- [tt]
#'require's and stuff...
dict = Dictionary.new(dict_names)
dict.get_max_cost()
test.rb:20: [BUG] Segmentation fault
ruby 1.7.0 (2001-05-17) [i686-linux]
Aborted [/tt]
-----------------------------
and also:
----------------------------- [tt]
dict = Dictionary.new(dict_names)
dict = nil
GC.start
test.rb:21: [bug] rb_gc_mark(): unknown data type 0x28(0x4034b690) corrupted object
ruby 1.7.0 (2001-05-17) [i686-linux]
Aborted [/tt]
-----------------------------
i know - ruby version 1.7.0, but i tried it with 1.6.3 to the same effect, so that's not an issue. for the most part, this seems to have the same structure as the example that Dave and /\ndy give in their book (p. 181), but, well i don't know - if i knew how to debug c stuff better, i could probly figure this out on my own, but, as it is, i've hit a dead end as to how i should attack this problem. i've tried pre-ALLOC-ing the Dictionary struct, but dictionary_create does that for itself:
--------------------------------------- [tt]
static Dictionary internal_dictionary_create(char * dict_name, char * pp_name, char * cons_name, char * affix_name, char * path) {
Dictionary dict;
static int rand_table_inited=FALSE;
Dict_node *dict_node;
char * dictionary_path_name;
dict = (Dictionary) xalloc(sizeof(struct Dictionary_s));
/* then fills that structure */ [/tt]
---------------------------------------
(note: in addition to 'xalloc', the program i'm wrapping also defines and uses an 'xfree'. this matters only because ruby.h has a macro that redefines 'xfree' to 'ruby_xfree' - i get errors unless i include the program's files before ruby's.)
there's lots of other things i've tried, in fact i've came up with a few more ideas while writing this letter, but (...time passes) to no avail. all i think i'm asking for is suggestions on where i should look to solve this.
thank you, anyone who takes the time to consider this,
stillflame "If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito."