SciRuby / rubex

rubex - A Ruby-like language for writing Ruby C extensions.
BSD 2-Clause "Simplified" License
451 stars 21 forks source link

Attach class : make fails #20

Closed kojix2 closed 7 years ago

kojix2 commented 7 years ago

Hello.

5 has been resolved. Thank you.

Now I'd like to try an attached class. After yesterday's update, rubex can compile attach class. That is great! However make fails. This is the error message of the c_struct_interface example.

I am sorry if the attach class is under development and the message is not a problem.

rubex rubex c_struct_interface.rubex
cd c_struct_interface
ruby extconf.rb
make

Error message

compiling c_struct_interface.c
c_struct_interface.c:63:9: error: passing '__rubex_t_Music_Music_data_struct'
      (aka 'struct Music_data_struct') to parameter of incompatible type
      'void *'
  xfree(__rubex_ptr_data[0]);
        ^~~~~~~~~~~~~~~~~~~
/path/2.4.1/include/ruby-2.4.0/ruby/defines.h:201:17: note: 
      passing argument to parameter here
void xfree(void*);
                ^
c_struct_interface.c:77:37: warning: incompatible pointer types initializing
      'size_t (*)(const void *)' (aka 'unsigned long (*)(const void *)') with an
      expression of type 'size_t (void *)' (aka 'unsigned long (void *)')
      [-Wincompatible-pointer-types]
  {0, __rubex_c_f_Music_deallocate, __rubex_c_f_Music_memcount,
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
make: *** [c_struct_interface.o] Error 1

This is the generated C file.

/* C extension for c_struct_interface.
This file in generated by Rubex::Compiler. Do not change!
File generation time: 2017-08-28 09:22:59 +0900.*/

#include <ruby.h>
#include <stdint.h>
#include <stdbool.h>
#include <ruby.h>

#define __rubex_INT2BOOL(arg) (arg ? Qtrue : Qfalse)

typedef struct mp3info
{
  char* __rubex_ptr_artist;
  char* __rubex_ptr_title;
  int __rubex_v_id;
} __rubex_t_Object_mp3info;

typedef struct Music_data_struct
{
  __rubex_t_Object_mp3info* __rubex_ptr_mp3info;
} __rubex_t_Music_Music_data_struct;

VALUE rb_cObject;
VALUE __rubex_rb_cls_Music;
static VALUE __rubex_rb_f_Music_initialize (int argc,VALUE* argv,VALUE __rubex_arg_self);
static VALUE __rubex_rb_f_Music_artist (int argc,VALUE* argv,VALUE __rubex_arg_self);
static VALUE __rubex_rb_f_Music_title (int argc,VALUE* argv,VALUE __rubex_arg_self);
static VALUE __rubex_rb_f_Music_id (int argc,VALUE* argv,VALUE __rubex_arg_self);
static void __rubex_c_f_Music_deallocate (void* __rubex_arg_raw_data);
static VALUE __rubex_c_f_Music_allocate (VALUE __rubex_arg_self);
static size_t __rubex_c_f_Music_memcount (void* __rubex_arg_raw_data);
static __rubex_t_Music_Music_data_struct* __rubex_c_f_Music_get_struct (VALUE __rubex_arg_obj);

VALUE __rubex_char2rubystr(char ch);
VALUE __rubex_char2rubystr(char ch)
{
  char s[2];
  s[0] = ch;
  s[1] = '\0';
  return rb_str_new2(s);
}

static void __rubex_c_f_Music_deallocate (void* __rubex_arg_raw_data)
{
  __rubex_t_Music_Music_data_struct* __rubex_ptr_data;
  __rubex_ptr_data = (__rubex_t_Music_Music_data_struct*)__rubex_arg_raw_data;

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:37 */
  xfree(__rubex_ptr_data[0].__rubex_ptr_mp3info->__rubex_ptr_artist);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:38 */
  xfree(__rubex_ptr_data[0].__rubex_ptr_mp3info->__rubex_ptr_title);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:39 */
  xfree(__rubex_ptr_data[0].__rubex_ptr_mp3info);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:40 */
  xfree(__rubex_ptr_data[0]);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:54 */
  xfree(__rubex_ptr_data);
}

static size_t __rubex_c_f_Music_memcount (void* __rubex_arg_raw_data)
{
  return sizeof(__rubex_arg_raw_data);

}

static const rb_data_type_t __rubex_attach_rb_cls_Music_data_type_t = {
  "Music",
  {0, __rubex_c_f_Music_deallocate, __rubex_c_f_Music_memcount,
  0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};

static __rubex_t_Music_Music_data_struct* __rubex_c_f_Music_get_struct (VALUE __rubex_arg_obj)
{
  __rubex_t_Music_Music_data_struct *data;

  TypedData_Get_Struct(__rubex_arg_obj, __rubex_t_Music_Music_data_struct, &__rubex_attach_rb_cls_Music_data_type_t, data);
  return data;
}

static VALUE __rubex_c_f_Music_allocate (VALUE __rubex_arg_self)
{
  __rubex_t_Music_Music_data_struct *data;

  data = (__rubex_t_Music_Music_data_struct*)xmalloc(sizeof(__rubex_t_Music_Music_data_struct));
  data->__rubex_ptr_mp3info = (__rubex_t_Object_mp3info*)xmalloc(sizeof(__rubex_t_Object_mp3info));
  return TypedData_Wrap_Struct(__rubex_arg_self,&__rubex_attach_rb_cls_Music_data_type_t, data);
}

static VALUE __rubex_rb_f_Music_initialize (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  VALUE __rubex_arg_artist;
  VALUE __rubex_arg_title;
  VALUE __rubex_arg_id;
  __rubex_t_Music_Music_data_struct* __rubex_ptr_data;
  __rubex_t_Object_mp3info* __rubex_ptr_mp3;
  int __rubex_v_a_size;
  int __rubex_v_t_size;
  if (argc < 3)
  {
    rb_raise(rb_eArgError, "Need 3 args, not %d", argc);
  }

  __rubex_arg_artist=argv[0];
  __rubex_arg_title=argv[1];
  __rubex_arg_id=argv[2];
  __rubex_ptr_data = __rubex_c_f_Music_get_struct(__rubex_arg_self);
  __rubex_ptr_mp3 = __rubex_ptr_data[0].__rubex_ptr_mp3info;
  __rubex_v_a_size = NUM2INT(rb_funcall(__rubex_arg_artist, rb_intern("size"), 0, NULL));
  __rubex_v_t_size = NUM2INT(rb_funcall(__rubex_arg_title, rb_intern("size"), 0, NULL));

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:23 */
  __rubex_ptr_mp3->__rubex_ptr_artist = (char*)xmalloc(( sizeof(char) * __rubex_v_a_size ));

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:24 */
  __rubex_ptr_mp3->__rubex_ptr_artist = StringValueCStr(__rubex_arg_artist);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:26 */
  __rubex_ptr_mp3->__rubex_ptr_title = (char*)xmalloc(( sizeof(char) * __rubex_v_t_size ));

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:27 */
  __rubex_ptr_mp3->__rubex_ptr_title = StringValueCStr(__rubex_arg_title);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:29 */
  __rubex_ptr_mp3->__rubex_v_id = NUM2INT(__rubex_arg_id);
}

static VALUE __rubex_rb_f_Music_artist (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  __rubex_t_Music_Music_data_struct* __rubex_ptr_data;
  if (argc < 0)
  {
    rb_raise(rb_eArgError, "Need 0 args, not %d", argc);
  }

  __rubex_ptr_data = __rubex_c_f_Music_get_struct(__rubex_arg_self);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:44 */
  return rb_str_new2(__rubex_ptr_data[0].__rubex_ptr_mp3info->__rubex_ptr_artist);
}

static VALUE __rubex_rb_f_Music_title (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  __rubex_t_Music_Music_data_struct* __rubex_ptr_data;
  if (argc < 0)
  {
    rb_raise(rb_eArgError, "Need 0 args, not %d", argc);
  }

  __rubex_ptr_data = __rubex_c_f_Music_get_struct(__rubex_arg_self);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:48 */
  return rb_str_new2(__rubex_ptr_data[0].__rubex_ptr_mp3info->__rubex_ptr_title);
}

static VALUE __rubex_rb_f_Music_id (int argc,VALUE* argv,VALUE __rubex_arg_self)
{
  __rubex_t_Music_Music_data_struct* __rubex_ptr_data;
  if (argc < 0)
  {
    rb_raise(rb_eArgError, "Need 0 args, not %d", argc);
  }

  __rubex_ptr_data = __rubex_c_f_Music_get_struct(__rubex_arg_self);

  /* Rubex file location: /path//rubex/examples/c_struct_interface/c_struct_interface.rubex:52 */
  return INT2NUM(__rubex_ptr_data[0].__rubex_ptr_mp3info->__rubex_v_id);
}

void Init_c_struct_interface ();
void Init_c_struct_interface ()
{
  VALUE __rubex_rb_cls_Music;

  __rubex_rb_cls_Music = rb_define_class("Music", rb_cObject);
  rb_define_alloc_func(__rubex_rb_cls_Music, __rubex_c_f_Music_allocate);

  rb_define_method(__rubex_rb_cls_Music ,"initialize", __rubex_rb_f_Music_initialize, -1);
  rb_define_method(__rubex_rb_cls_Music ,"artist", __rubex_rb_f_Music_artist, -1);
  rb_define_method(__rubex_rb_cls_Music ,"title", __rubex_rb_f_Music_title, -1);
  rb_define_method(__rubex_rb_cls_Music ,"id", __rubex_rb_f_Music_id, -1);
}
v0dro commented 7 years ago

You're using the outdated example. I have updated the example with the latest commit. Please check that.

kojix2 commented 7 years ago

Thank you very much. I confirmed.

I will use data$ instead of instance variables, but is it ok to use data$ for such purpose? not reccomended?

v0dro commented 7 years ago

data$ is a specific variable only available inside attach classes for accessing values of structs. You should not use it for anything else. See the reference: https://github.com/v0dro/rubex/blob/master/REFERENCE.md#the-data-variable