Init_xxx(with arg ??) in C for ruby ext ???

U

Une bévue

hey all,

new to C, i'm writing a ruby ext, i wonder if we could pass an arg to
Init_xxx(type * arg) ???

this is to have a constructor in ruby like that :

trick=MyClass.new("my arg")

and if not does exists a workaround ???
 
U

Une bévue

Une bévue said:
ew to C, i'm writing a ruby ext, i wonder if we could pass an arg to
Init_xxx(type * arg) ???

this is to have a constructor in ruby like that :

trick=MyClass.new("my arg")

and if not does exists a workaround ???

it is :

rb_define_singleton_method(rb_cMyClass, "new", cd_new, 1);
 
E

Eric Hodel

hey all,

new to C, i'm writing a ruby ext, i wonder if we could pass an arg to
Init_xxx(type * arg) ???

this is to have a constructor in ruby like that :

trick=3DMyClass.new("my arg")

and if not does exists a workaround ???

The Init_ method initializes the shared library, it is not the =20
constructor.

Write your #initialize to take arguments and MyClass.new "my arg" =20
will work.

--=20
Eric Hodel - (e-mail address removed) - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
 
Y

Yvon Thoraval

Le 9 ao=FBt 06 =E0 00:21, Eric Hodel a =E9crit :
On Aug 8, 2006, at 12:13 PM, Eric Hodel wrote:
[snip]
Oops.

rb_define_method(rb_cMyClass, "initialize", cd_initialize, 1);


ok thanks, i get it, now i've an init like that :

VALUE method_raliasfile_init(VALUE self, char * alias_path)
{
rb_iv_set(self, "@alias_path", *alias_path);
return self;
}

declared in :

void Init_raliasfile() {
cRAliasFile =3D rb_define_class("RAliasFile", rb_cObject);
rb_define_singleton_method(cRAliasFile, "new", =20
method_raliasfile_new, 1);
rb_define_method(RAliasFile, "initialize", =20
method_raliasfile_init, 1);
rb_define_method(RAliasFile, "alias_path", method_alias_path, =20=

0);
rb_define_method(RAliasFile, "orig_path", method_orig_path, 0);
rb_define_method(RAliasFile, "is_alias_file", =20
method_is_alias_file, 0);
rb_define_method(RAliasFile, "is_alias_broken", =20
method_is_alias_broken, 0);
rb_define_method(RAliasFile, "is_folder", method_is_folder, 0);
rb_define_method(RAliasFile, "is_data_file", =20
method_is_data_file, 0);
}


and i want the arg "alias_path" to be "global" to all of the methods =20
of this class, what to do for that ???

best,

Yvon=
 
E

Eric Hodel

Le 9 ao=FBt 06 =E0 00:21, Eric Hodel a =E9crit :
On Aug 8, 2006, at 12:13 PM, Eric Hodel wrote:
[snip]
Oops.

rb_define_method(rb_cMyClass, "initialize", cd_initialize, 1);


ok thanks, i get it, now i've an init like that :

VALUE method_raliasfile_init(VALUE self, char * alias_path)
{
rb_iv_set(self, "@alias_path", *alias_path);
return self;
}

declared in :

void Init_raliasfile() {
cRAliasFile =3D rb_define_class("RAliasFile", rb_cObject);
rb_define_singleton_method(cRAliasFile, "new", =20
method_raliasfile_new, 1);

^^^ remove this line ^^^

You don't need to define new.
rb_define_method(RAliasFile, "initialize", =20
method_raliasfile_init, 1);
rb_define_method(RAliasFile, "alias_path", =20
method_alias_path, 0);
rb_define_method(RAliasFile, "orig_path", method_orig_path, =20=
0);
rb_define_method(RAliasFile, "is_alias_file", =20
method_is_alias_file, 0);
rb_define_method(RAliasFile, "is_alias_broken", =20
method_is_alias_broken, 0);
rb_define_method(RAliasFile, "is_folder", method_is_folder, =20=
0);
rb_define_method(RAliasFile, "is_data_file", =20
method_is_data_file, 0);
}

--=20
Eric Hodel - (e-mail address removed) - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com
 
U

Une bévue

Eric Hodel said:
^^^ remove this line ^^^

You don't need to define new.

i get an eror now :
RAliasFile.c: In function 'method_alias_path':
RAliasFile.c:46: error: request for member 'alias_path' in something not
a structure or union

then, i think i have to do something like that :
typedef struct _raf {
int is_alias_file;
int is_folder;
int is_data_file;
char * alias_path;
char * orig_path;
char * version;
} RAliasFile;
 
N

nobu

Hi,

At Wed, 9 Aug 2006 07:55:52 +0900,
Yvon Thoraval wrote in [ruby-talk:207182]:
VALUE method_raliasfile_init(VALUE self, char * alias_path)
{
rb_iv_set(self, "@alias_path", *alias_path);
return self;
}

All arguments are passed as VALUE, not C type.

VALUE method_raliasfile_init(VALUE self, VALUE alias_path)
{
rb_iv_set(self, "@alias_path", alias_path);
return self;
}
 
U

Une bévue

All arguments are passed as VALUE, not C type.

VALUE method_raliasfile_init(VALUE self, VALUE alias_path)
{
rb_iv_set(self, "@alias_path", alias_path);
return self;
}

then this arg "VALUE alias_path" will be common to all of the methods i
have ?

it seems not (???)

i've change my init for debugg purpose to :


VALUE m_raliasfile_init(VALUE self, VALUE alias_path)
{
printf("m_raliasfile_init");
printf((char *)alias_path);
printf("alias_path");
rb_iv_set(self, "@alias_path", alias_path);
return self;
}


and, when i use my class from ruby i do :

a=RAliasFile.new("/Users/yvon/work/Ruby/Native/C/doc/Introduction_ANSI_C
_html")
puts a.alias_path

the print out (from C) being :

m_raliasfile_initalias_path

which means the arg "alias_path" isn't pass to "m_raliasfile_init"

the ruby line "puts a.alias_path" gives :

ArgumentError: NULL pointer given

where the C counterpart being :
VALUE m_alias_path(VALUE self) {
// char *alias_path = "/path/to/something/undefined";
return rb_str_new2((char *) alias_path);
}


what i want is my class "RAliasFile" being initialize like that (from
ruby) :

a=RAliasFile.new("/Users/yvon/work/Ruby/Native/C/doc/Introduction_ANSI_C
_html")

the parameter of "new" being alias_path bar in the C counterpart...

i'm a newb in C as you can see, that's (will be) my first extension..
 
T

ts

Post your *complete* source

U> where the C counterpart being :
U> VALUE m_alias_path(VALUE self) {
U> // char *alias_path = "/path/to/something/undefined";
U> return rb_str_new2((char *) alias_path);
U> }

This is just a nonsense. You define an instance variable @alias_path then
you try to retrieve a local C variable alias_path rather than the instance
variable.


Guy Decoux
 
U

Une bévue

ts said:
Post your *complete* source

U> where the C counterpart being :
U> VALUE m_alias_path(VALUE self) {
U> // char *alias_path = "/path/to/something/undefined";
U> return rb_str_new2((char *) alias_path);
U> }

This is just a nonsense. You define an instance variable @alias_path then
you try to retrieve a local C variable alias_path rather than the instance
variable.

ok thanks a lot for your clear answer ;-)

--- RAliasFile.h--------------------------------------------------------
void Init_raliasfile();

VALUE m_raliasfile_init(VALUE self, VALUE alias_path);
VALUE m_raliasfile_new(VALUE self, VALUE alias_path);
VALUE m_set_alias_path(VALUE self, VALUE alias_path);
VALUE m_alias_path(VALUE self);
VALUE m_orig_path(VALUE self);
VALUE m_is_alias_file(VALUE self);
VALUE m_is_alias_file_broken(VALUE self);
VALUE m_is_folder(VALUE self);
VALUE m_is_data_file(VALUE self);
VALUE m_version(VALUE self);
------------------------------------------------------------------------
--- RAliasFile.c--------------------------------------------------------
//
// RAliasFile.c
//

#include "ruby.h"
#include "RAliasFile.h"

VALUE RAliasFile = Qnil;
VALUE cRAliasFile;
VALUE alias_path;

/**/
struct RAliasFile {
VALUE alias_path;
char *orig_path;
int alias_file;
int alias_file_broken;
int folder;
int data_file;
char *version;
};
/**/

void Init_raliasfile() {
cRAliasFile = rb_define_class("RAliasFile", rb_cObject);
rb_define_method(RAliasFile, "initialize",
m_raliasfile_init, 1);
rb_define_method(RAliasFile, "new",
m_raliasfile_new, 1);
rb_define_method(RAliasFile, "set_alias_path",
m_set_alias_path, 1);
rb_define_method(RAliasFile, "alias_path", m_alias_path,
0);
rb_define_method(RAliasFile, "orig_path", m_orig_path, 0);
rb_define_method(RAliasFile, "is_alias_file", m_is_alias_file,
0);
rb_define_method(RAliasFile, "is_alias_file_broken",
m_is_alias_file_broken, 0);
rb_define_method(RAliasFile, "is_folder", m_is_folder, 0);
rb_define_method(RAliasFile, "is_data_file", m_is_data_file,
0);
rb_define_method(RAliasFile, "version", m_version, 0);
}

VALUE m_raliasfile_init(VALUE self, VALUE _alias_path)
{
alias_path = _alias_path;
printf("From C => alias_path : %s\n", alias_path);
rb_iv_set(self, "@alias_path", alias_path);
return self;
}

VALUE m_raliasfile_new(VALUE self, VALUE _alias_path) {
rb_iv_set(self, "@alias_path", alias_path);
printf("m_raliasfile_new");
alias_path = _alias_path;
return self;
}

VALUE m_set_alias_path(VALUE self, VALUE _alias_path) {
alias_path = _alias_path;
rb_iv_set(self, "@alias_path", alias_path);
// return rb_str_new2((char *) alias_path);
}

VALUE m_alias_path(VALUE self) {
// char *alias_path = "/path/to/something/undefined";
return rb_str_new2((char *) alias_path);
}

VALUE m_orig_path(VALUE self) {
char *orig_path = "/Users/yvon/work/Ruby/Native/RubyInline-3.5.0.gem";
return rb_str_new2(orig_path);
}

VALUE m_is_alias_file(VALUE self) {
int alias_file = 1;
return INT2FIX(alias_file);
}

VALUE m_is_alias_file_broken(VALUE self) {
int alias_file_broken = 0;
return INT2FIX(alias_file_broken);
}

VALUE m_is_folder(VALUE self) {
int folder = 0;
return INT2FIX(folder);
}

VALUE m_is_data_file(VALUE self) {
int data_file = 0;
return INT2FIX(data_file);
}

VALUE m_version(VALUE self) {
char *version = "0.0.1";
return rb_str_new2(version);
}
------------------------------------------------------------------------
--- raliasfile_test.rb -------------------------------------------------
#!/usr/bin/env ruby
#
# raliastest.rb
#

require 'osx/ralias/raliasfile'

a=RAliasFile.new("/Users/yvon/work/Ruby/Native/C/doc/Introduction_ANSI_C
_html")

#From C => alias_path :

a.set_alias_path("/Users/yvon/work/Ruby/Native/C/doc/Introduction_ANSI_C
_html")

puts a.alias_path
# =>

puts a.orig_path
# => /Users/yvon/work/Ruby/Native/RubyInline-3.5.0.gem

puts a.is_alias_file
# => 1

puts a.is_alias_file_broken
# => 0

puts a.is_folder
# => 0

puts a.is_data_file
# => 0

puts a.version
# => 0.0.1
 
T

ts

U> /**/
U> struct RAliasFile {
U> VALUE alias_path;
U> char *orig_path;
U> int alias_file;
U> int alias_file_broken;
U> int folder;
U> int data_file;
U> char *version;
U> };
U> /**/

Useless actually because you use instance variable rather than C struct.

If you really want to use C struct, see Data_Make_Struct() and the
examples given in README.EXT or ruby-x.x.x/ext/*

U> void Init_raliasfile() {
U> cRAliasFile = rb_define_class("RAliasFile", rb_cObject);
U> rb_define_method(RAliasFile, "initialize",
U> m_raliasfile_init, 1);
U> rb_define_method(RAliasFile, "new",
U> m_raliasfile_new, 1);

remove this method #new

U> rb_define_method(RAliasFile, "set_alias_path",
^^^^^^^^^^^^^^^
"alias_path="

U> m_set_alias_path, 1);
U> rb_define_method(RAliasFile, "alias_path", m_alias_path,
U> 0);
U> rb_define_method(RAliasFile, "orig_path", m_orig_path, 0);
U> rb_define_method(RAliasFile, "is_alias_file", m_is_alias_file,
^^^^^^^^^^^^^^^
"is_alias_file?",

U> 0);
U> rb_define_method(RAliasFile, "is_alias_file_broken",
U> rb_define_method(RAliasFile, "is_folder", m_is_folder, 0);
U> rb_define_method(RAliasFile, "is_data_file", m_is_data_file,
U> 0);

same here


U> VALUE m_raliasfile_init(VALUE self, VALUE _alias_path)
U> {
U> alias_path = _alias_path;

remove this variable alias_path

U> printf("From C => alias_path : %s\n", alias_path);

You have a VALUE not a char *, you must first convert it to (char *)
before trying to print it (with, for example, StringValuePtr(), see
README.EXT)


U> rb_iv_set(self, "@alias_path", alias_path);

rb_iv_set(self, "@alias_path", _alias_path);

U> return self;
U> }

U> VALUE m_raliasfile_new(VALUE self, VALUE _alias_path) {
U> rb_iv_set(self, "@alias_path", alias_path);
U> printf("m_raliasfile_new");
U> alias_path = _alias_path;
U> return self;
U> }

Useless actually : remove it


U> VALUE m_set_alias_path(VALUE self, VALUE _alias_path) {
U> alias_path = _alias_path;
U> rb_iv_set(self, "@alias_path", alias_path);
U> // return rb_str_new2((char *) alias_path);
U> }

U> VALUE m_alias_path(VALUE self) {
U> // char *alias_path = "/path/to/something/undefined";
U> return rb_str_new2((char *) alias_path);

You have defined an instance variable : retrieve it. *Don't* use a global
C variable when you work with instance variable

return rb_iv_get(self, "@alias_path");

U> }

U> VALUE m_orig_path(VALUE self) {
U> char *orig_path = "/Users/yvon/work/Ruby/Native/RubyInline-3.5.0.gem";
U> return rb_str_new2(orig_path);
U> }

U> VALUE m_is_alias_file(VALUE self) {
U> int alias_file = 1;
U> return INT2FIX(alias_file);

return Qtrue or Qfalse (not a Fixnum)

U> }



Guy Decoux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,209
Messages
2,571,088
Members
47,687
Latest member
IngridXxj

Latest Threads

Top