Help with C embedding

I’m having trouble with a weird error that I don’t understand the cause
of. I’m pretty new to embedding so I’m sure I’m overlooking something.

The relevant C code is as follows:

VALUE input_trigger(VALUE button) {
PspCtrlButtons cbutt = (PspCtrlButtons)NUM2ULONG(button);
if((pad.Buttons & cbutt) && !(oldpad.Buttons & cbutt)) {return Qtrue;}
return Qfalse;
}

//this gets called during initialization:
rb_define_module_function(ruby_input_mod, “trigger?”,
(VALUE (*)(…))input_trigger, 1);

I get errors when calling the method though:

result = Input.trigger?(16)

It’s saying

can’t convert Module into Integer

I don’t understand why it expects a Module there.

Can anyone see what I’m doing wrong here?

I’d really appreciate any advice. :slight_smile:

Khat H. wrote:

VALUE input_trigger(VALUE button) {

Try:

VALUE input_trigger(VALUE self, VALUE button) {

There are some examples you can follow at
http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html

Have a look at the first one and compare it to yours:

static VALUE t_add(VALUE self, VALUE anObject)
{

}

rb_define_method(cTest, “add”, t_add, 1);

result = Input.trigger?(16)

It’s saying

can’t convert Module into Integer

I don’t understand why it expects a Module there.

Input is a module, and is the receiver of the method call.

Khat H. wrote:

I’m having trouble with a weird error that I don’t understand the cause
of.

The error is coming from this line:

PspCtrlButtons cbutt = (PspCtrlButtons)NUM2ULONG(button);

Specifically, the function call:

NUM2ULONG(button)

As Brian C. pointed out, your function signature here is faulty:

VALUE input_trigger(VALUE button)

You are actually doing something like this:

static VALUE input_trigger(VALUE self)
{
  unsigned long num = NUM2ULONG(self);
}

The first parameter variable of a function automatically gets assigned
self. As a consequence, if you want to pass one argument to a
function, you have to define the function with two parameter variables:
the first parameter variable will be assigned self, and the second
parameter variable will be assigned the argument you pass.

In your code, the first parameter variable is named ‘button’, and when
you call the function, self is automatically assigned to the first
parameter variable, so self gets assigned to button. Because a module
is calling the function, self is the module, and the function NUM2ULONG
can’t convert a module to an int (an unsigned long integer in this
case).

//this gets called during initialization:
rb_define_module_function(ruby_input_mod, “trigger?”,
(VALUE (*)(…))input_trigger, 1);

Next, that cast to a variadic function produces an error when I compile
the code:

error: ISO C requires a named argument before ‘…’

Awesome. Works like a charm. I’ll read through that chapter. Thank
you.

I’m using gcc to compile and it doesn’t have a problem with the variadic
cast, but yeah, I should probably clean that up anyway.

Thanks again guys. :slight_smile:

Khat H. wrote:

I’m using gcc to compile and it doesn’t have a problem with the variadic
cast

Probably best just to copy what Ruby does.

[defines.h]
#ifdef __cplusplus
#define ANYARGS …
#else
#define ANYARGS
#endif

[ruby.h]
void rb_define_module_function _((VALUE,const
char*,VALUE(*)(ANYARGS),int));

[class.c uses K&R prototypes :-(]
void
rb_define_module_function(module, name, func, argc)
VALUE module;
const char *name;
VALUE (*func)();
int argc;