[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Ruby arguments into C function are warped

Daniel Waite

12/31/2008 9:19:00 PM

I want to code a few methods in C for speed reasons. The Pick Axe book
(2nd edition) is a wonderful guide to writing Ruby code in C, but that's
not what I want. The benchmarks I ran for the Ruby-in-Ruby and Ruby-in-C
programs showed similar results. So allow me to clarify:

I do not want a Ruby array in C. I want a C array in C.

Which I have done...

int array[1000000];

static VALUE t_add(VALUE self, VALUE obj, VALUE i)
{
array[i] = obj;
return 1;
}

static VALUE t_include(VALUE self, VALUE obj)
{
int size = sizeof(array) / sizeof(int);
int index;

for(index = 0; index < size; index++) {
if(FIX2INT(obj) == FIX2INT(array[index])) {
return Qtrue;
}
}

return Qfalse;
}

static VALUE t_at(VALUE self, VALUE obj)
{
return array[obj];
}

The value of "obj" comes from within Ruby (IRB, actually). But unless I
coerce it using FIX2INT, it's always a weird value. Say I put in 1,
it'll tell me it received 31478 or something similar.

Another thing... I thought that if I passed in an 'a' or any other
non-integer value into the add method, I'd get an error. I don't. In
fact...

require 'my_test'
mt = MyTest.new
mt.add('a', 0)
mt.at(0) # 'a'

But...

mt.include?('a') # false

So... what's happening to my arguments as they pass through Ruby and
into C?
--
Posted via http://www.ruby-....

5 Answers

Evolution

12/31/2008 9:15:00 PM

0

HalS007 wrote:
> On Dec 31, 10:34 am, Evolution <myn...@rcn.com> wrote:
>> HalS007 wrote:
>>> I think that if Obama/Clinton wanted to make a statement agreeing with
>>> all the others, it would cost them nothing. That they are silent
>>> makes
>>> me think that at least they are considering the truth.>>
>>> Obama has not been silent. He himself has not spoken but David
>>> Axelrod, his spokesperson has, and when asked about the situation
>>> Axelrod referred people back to Obama's previous statement. That has
>>> been widely reported.
>>> "Speaking on CBS's Face the Nation, his chief adviser, David Axelrod,
>>> initially repeated the Obama team's formula that there could only be
>>> one president at a time and that president was George Bush.
>>> But he went on to recall comments that Obama made in July at Sderot,
>>> the Israeli town that is the target of rocket attacks from Palestinian
>>> militants in Gaza.
>>> At the time, Obama said : "If somebody was sending rockets into my
>>> house where my two daughters sleep at night, I'm going to do
>>> everything in my power to stop that. I would expect Israelis to do the
>>> same thing."
>> Right, the statement that he would do everything in his power to make
>> the shelling stop. No way is that statement a blanket support for
>> Israel. He did not even say anything about self-defense, like all the
>> others. You can read what you want into it, but it was a carefully
>> worded statement which did not justify Israel's actions in any way.
>>
>> --
>> Laurie
>>
>> http://lauriehester.blo...
>
> The words "do everything in my power to stop" are all about self-
> defense. He's saying clearly that he would resort to any measure,
> including the use of military power in self defense, to stop the
> attacks.

No, that's not what he said. He very carefully avoided any mention of
"self-defense" as other politicians are using.

There are many ways to stop those attacks; bombing the Palestinians for
over 40 years hasn't stopped it, but maybe this time, it will. Oh,
wait, all through the most recent bombing campaign, killing hundreds of
civilians, the missiles didn't stop.

The point is, the best way to stop these attacks is for Israel to stop
the blockade, accept the results of a democratic election, and THAT is
what Obama is referring to.

And it's ridiculous that you are trying to claim otherwise
> since Obama has been roundly condemned for that remark for that very
> reason by your anti-Israeli wacko friends on the Net.

You are reading something into his statement which isn't there, based on
your acceptance of the premise that somehow Israel bombing the shit out
of children is going to stop the attacks, when Israel is the aggressor
and is blockading Gaza to the point where they are suffering terribly.

Again, Israel is NOT acting in self-defense, as they are the aggressors,
and Obama very carefully didn't mention anything about self-defense. He
only mentioned stopping the attacks, something which Israel is NOT going
to do with their current policies. If Israel cannot stop the attacks
this way, why would you assume Obama is referring to supporting their
current policies when he says he would stop the attacks?


--
Laurie

http://lauriehester.blo...

Tim Hunter

12/31/2008 10:48:00 PM

0

Daniel Waite wrote:
> I want to code a few methods in C for speed reasons. The Pick Axe book
> (2nd edition) is a wonderful guide to writing Ruby code in C, but that's
> not what I want. The benchmarks I ran for the Ruby-in-Ruby and Ruby-in-C
> programs showed similar results. So allow me to clarify:
>
> I do not want a Ruby array in C. I want a C array in C.
>
> Which I have done...
>
> int array[1000000];
>
> static VALUE t_add(VALUE self, VALUE obj, VALUE i)
> {
> array[i] = obj;
> return 1;
> }
>
> static VALUE t_include(VALUE self, VALUE obj)
> {
> int size = sizeof(array) / sizeof(int);
> int index;
>
> for(index = 0; index < size; index++) {
> if(FIX2INT(obj) == FIX2INT(array[index])) {
> return Qtrue;
> }
> }
>
> return Qfalse;
> }
>
> static VALUE t_at(VALUE self, VALUE obj)
> {
> return array[obj];
> }
>
> The value of "obj" comes from within Ruby (IRB, actually). But unless I
> coerce it using FIX2INT, it's always a weird value. Say I put in 1,
> it'll tell me it received 31478 or something similar.
>
> Another thing... I thought that if I passed in an 'a' or any other
> non-integer value into the add method, I'd get an error. I don't. In
> fact...
>
> require 'my_test'
> mt = MyTest.new
> mt.add('a', 0)
> mt.at(0) # 'a'
>
> But...
>
> mt.include?('a') # false
>
> So... what's happening to my arguments as they pass through Ruby and
> into C?

Notice that you've declared the arguments to t_add as VALUEs, not ints.
This is because Ruby passes VALUE arguments to your function. A VALUE is
a reference to a Ruby object. If you want to store the arguments in an
int array, convert the objects to ints via FIX2INT or some other
conversion function:

static VALUE t_add(VALUE self, VALUE obj, VALUE i)
{
array[FIX2INT(i)] = FIX2INT(obj);
return self;
}

A VALUE can reference any Ruby object, but the FIX2INT macro expects its
argument to be a Ruby Fixnum. If it's not, it will raise an exception.
You'll get an exception if you call mt.add("a", 0).

Also, the return value from t_add should be a VALUE, not an int. It's
your choice which VALUE to return. Here I chose self.

--
RMagick: http://rmagick.ruby...

Morris Keesan

1/1/2009 5:28:00 AM

0

Also: not a Ruby issue, but a C issue: You've left yourself wide open
for a buffer overflow. Unless your Ruby code somehow guarantees that
the value of i will always be within the range 0..999999 (in which
case it really should be documented, and probably in a Ruby CONSTANT
and C #define), it's inevitable that some day some code will pass in a
negative value, or a value of 1000000 or greater, and your code will
mysteriously stop working correctly. Make sure, every time you access
your array, but especially when assigning to it, that you check that
the index is valid.

Brian Candler

1/1/2009 8:51:00 AM

0

Have a look at the RubyInline gem, and FFI
--
Posted via http://www.ruby-....

Daniel Waite

1/3/2009 12:05:00 AM

0

Tim Hunter wrote:
> A VALUE can reference any Ruby object, but the FIX2INT macro expects its
> argument to be a Ruby Fixnum. If it's not, it will raise an exception.
> You'll get an exception if you call mt.add("a", 0).

Ah, that seems obvious now. Thanks for the help.

> Also, the return value from t_add should be a VALUE, not an int. It's
> your choice which VALUE to return. Here I chose self.

Agreed, and I originally was returning self (it's still commented in the
actual file) but I was trying to strip out all unnecessary code.

> Also: not a Ruby issue, but a C issue: You've left yourself wide open
> for a buffer overflow.

Fully aware, but thanks for the concern. ;)

Brian Candler wrote:
> Have a look at the RubyInline gem, and FFI

I've looked at RubyInline, and it was surprisingly easy to get it
working. I'm uncertain if it will do what I need it do though -- namely,
pass information back and forth between C and Ruby.

The FFI project looks interesting though... :)

Thanks for the excellent replies.
--
Posted via http://www.ruby-....