Wrapping a structure as a new class


#1

well i don’t know if my title is exactly what i mean…
anyway

I’m writing a C extension, which can create a Bitmap class.(I’m using
SDL)

So far, it’s working… for the initialization:

//========================================
VALUE cBitmap;

void sdl_freeSurface(SDL_Surface* surface)
{
SDL_FreeSurface(surface);
}

VALUE bitmap_init(int argc, VALUE *argv, VALUE self)
{
SDL_Surface *new_bitmap;

if (argc == 1)
{
Check_Type(argv[0],T_STRING);
new_bitmap=IMG_Load(STR2CSTR(argv[0]));
}
else
{
Check_Type(argv[0],T_FIXNUM);
Check_Type(argv[1],T_FIXNUM);

new_bitmap=SDL_CreateRGBSurface(SDL_HWSURFACE,FIX2UINT(argv[0]),FIX2UINT(argv[1]),32,0,0,0,0);
}
return Data_Wrap_Struct(cBitmap,0,sdl_freeSurface,new_bitmap);
}
//=========================================================

when i do a=Bitmap.new(23,32)
i got a bitmap object.
but here comes the problem:

I got an argument type error on the class methods…(a.width for
example):
"wrong argument type Bitmap "

I’ve understand that the wrapped structure is a T_DATA object… but
all I
want is to access this structure.
a class method example using which try to access the struct:
//===============================
VALUE bitmap_width(VALUE obj)
{
SDL_Surface *surface;
Data_Get_Struct(obj,SDL_Surface,surface);
return INT2FIX(surface->w);
}
//===============================

If i use the ‘self’ argument in the Data_wrap instead of cBitmap, I
can’t
create the object and got the same error: '… type Bitmap

So if someone can explain me :stuck_out_tongue: how to get back my structure…please.
^^
would be great!


#2

Arf^^… nobody answered, but it’s ok, I’ve solved my problem…
It’s just because, i didnt’ defined the initialize method as a singleton
method (other tutorials never told me to…, and it has always worked
so…)
Anyway, it works now! Raaaah it was so simple xD


#3

Hi,

At Mon, 11 Jun 2007 04:28:33 +0900,
trebor777 wrote in [ruby-talk:255046]:

Arf^^… nobody answered, but it’s ok, I’ve solved my problem…

We had a development camp and RubyKaigi2007 last week.

It’s just because, i didnt’ defined the initialize method as a singleton
method (other tutorials never told me to…, and it has always worked so…)
Anyway, it works now! Raaaah it was so simple xD

The initialize method must be an instance method. Rather
you’ll need the allocator function. You should not override
Class.new unless you have special reasons.

static VALUE
bitmap_s_alloc(VALUE klass)
{
return Data_Wrap_Struct(klass, 0, SDL_FreeSurface, 0);
}

static VALUE
VALUE bitmap_init(int argc, VALUE *argv, VALUE self)
{
SDL_Surface *new_bitmap;

switch (argc) {
  case 1:

new_bitmap = IMG_Load(StringValueCStr(argv[0]));
break;
case 2: {
unsigned int x = NUM2UINT(argv[0]), y = NUM2UINT(argv[1]);
new_bitmap = SDL_CreateRGBSurface(SDL_HWSURFACE, x, y, 32, 0, 0, 0,
0);
break;
default:
rb_raise(rb_eArgError, “wrong number of arguments (%d for 1 or 2)”,
argc);
}
DATA_PTR(self) = new_bitmap;
return self;
}

void
Init_bitmap(void)
{
VALUE cBitmap = rb_define_class(“Bitmap”, rb_cData);

rb_define_alloc_func(cBitmap, bitmap_s_alloc);
rb_define_method(cBitmap, "initialize", bitmap_init, -1);

}

I got an argument type error on the class methods…(a.width for example):
"wrong argument type Bitmap "

The default allocator function would be used.


#4

Ahh :slight_smile: Domo arigato! :stuck_out_tongue:
You’ve even rewritten my code! That’s great! really Thank you!

Sorry for the “nobody answered” i didn’t know about that camp… ^^"