thomas.luce
6/13/2006 2:38:00 PM
Yeah, I realize this. I didn't post some of the code because it wasn't
part of the issue I was having. I've been coding since I was 9, and
haven't done C in about 5 years, so it's starting to come back to me.
Anyway, I got it figured out already, but thank you for your input! It
is very appreciated!
-Thomas
Gerald Murray wrote:
> Hello Thomas,
>
> There is still a learning curve ahead of you for the C.
>
> There were parts of the code that were not posted, or missing:
> net_free()
> The function declarations (see Init_exx() following this part)
> There was no call to initialize the class. In the following
> example, look at rb_obj_call_init() which calls "initialize"
>
> The code had malloc() and calloc() calls, but no corresponding calls
> to free(). It would be a good improvement to use ruby's
> allocation to avoid memory leaks. See how this was done in the
> following example with the macro ALLOC(); this will be cleaned up
> when exx_free() is called. Data_Wrap_Struct passes the address
> of exx_free(). For just starting out, avoid using C allocation calls.
> You might find the following example helpful. To keep the debugging
> simple, start from a simple program that works; then add the more
> complex stuff later. Other examples of wrapping can be found in
> the ruby application archive at www.ruby-lang.org or www.rubyforge.net
>
> Good luck,
> Gerald
>
> -- FILE exx.c--
> /* exx.c */
> #include <ruby.h>
>
> typedef struct Udata{
> int c;
> }Udata;
>
> VALUE cExx;
>
> static VALUE
> exx_init(VALUE self, VALUE unit){
> return self;
> }
>
> static void
> exx_free(Udata *pr)
> {
> free(pr);
> }
>
> static VALUE
> exx_new(VALUE class)
> {
> VALUE argv[1],tt;
> Udata *pr;
> pr = ALLOC(Udata);
> tt = Data_Wrap_Struct(class,0,exx_free,pr);
> argv[0] = tt;
> rb_obj_call_init(tt,1,argv); // call exx_init to initialize
> pr->c = 0;
>
> return tt;
> }
>
> static VALUE
> exx_verify(VALUE self, VALUE num)
> {
> Udata *pr;
> int c = FIX2INT(num);
>
> Data_Get_Struct(self,Udata,pr);
> printf("val was %d, changed to %d\n",pr->c,c);
> pr->c = c;
>
> return self;
> }
>
> void Init_exx(){
> cExx = rb_define_class("Exx",rb_cObject);
> rb_define_singleton_method(cExx,"new",exx_new,0);
> rb_define_method(cExx,"initialize",exx_init,1);
> rb_define_method(cExx,"verify",exx_verify,1);
> }
>
> // vim: sts=2 sw=2 ts=4 et ai tw=77
>
> -- FILE extconf.rb --
> #extconf.rb
> require "mkmf"
> create_makefile("exx")
>
> -- FILE useexx.rb --
> #!/usr/bin/ruby
> #useexx.rb
> require 'exx'
>
> a = Exx.new()
> a.verify(1)
> a.verify(2)
> puts "that's all"
>
> -- PROGRAM --
> % ./useexx.rb
> val was 0, changed to 1
> val was 1, changed to 2
> that's all