[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

How to implement set_trace_func callback in C/C++?

Stephen Kellett

11/29/2004 8:27:00 PM

Hello everybody,

I'm trying to implement the callback for set_trace_func in C++. Think of
it as C if thats any easier. Shown at the bottom of this posting is my
sample application which runs the standard "Hello World" ruby program.

My callback function "my_trace_function" gets called. Problem is I don't
know how to access the event, file, line, id, binding and classname
parameters passed to the function which I'd have access to if coding in
Ruby.

Can anyone tell me how to get the parameters passed to the callback
function? Have I got the function prototype correct? Etc. I've shown it
as 3 VALUEs as that is what I think it is. Is it really implemented as
varargs or something else?

Hoping you can help. (Yes, I really do need the callback implemented in
C or C++, which is why I'm using C/C++ for the callback and not Ruby for
the callback).

I've done a Google on this subject and not found anyone else doing this.

Stephen

#include "ruby.h"

VALUE my_trace_function(VALUE count,
VALUE args,
VALUE other)
{
// is args an array? If so how to access properly
// I keep getting errors if I treat args as an array.

return 0;
}

int main(int argc, char* argv[])
{
NtInitialize(&argc, &argv);

ruby_init();
ruby_script("embedded");

VALUE module;

module = rb_define_module("TRACEMODULE");
rb_define_module_function(module,
"my_trace_func",
(unsigned long (__cdecl *)(...))my_trace_function,
-1);
rb_eval_string(
"set_trace_func proc {|*data| TRACEMODULE.my_trace_func(*data)}");

rb_load_file("e:\\ruby\\samples\\hello.rb");
ruby_run();

return 0;
}

--
Stephen Kellett
Object Media Limited http://www.objmedia.d...
RSI Information: http://www.objmedia.d.../rsi.html
5 Answers

Yukihiro Matsumoto

11/29/2004 11:38:00 PM

0

Hi,

In message "Re: How to implement set_trace_func callback in C/C++?"
on Tue, 30 Nov 2004 05:32:48 +0900, Stephen Kellett <snail@objmedia.demon.co.uk> writes:

|VALUE my_trace_function(VALUE count,
| VALUE args,
| VALUE other)
|{
| // is args an array? If so how to access properly
| // I keep getting errors if I treat args as an array.
|
| return 0;
|}

Try:

VALUE my_trace_function(int argc, VALUE *argv);

matz.


Stephen Kellett

11/30/2004 11:35:00 AM

0

In message <1101771510.124768.9696.nullmailer@x31.priv.netlab.jp>,
Yukihiro Matsumoto <matz@ruby-lang.org> writes
>Try:
>
> VALUE my_trace_function(int argc, VALUE *argv);

Thanks.
--
Stephen Kellett
Object Media Limited http://www.objmedia.d...
RSI Information: http://www.objmedia.d.../rsi.html

Stephen Kellett

11/30/2004 1:55:00 PM

0

In message <1101771510.124768.9696.nullmailer@x31.priv.netlab.jp>,
Yukihiro Matsumoto <matz@ruby-lang.org> writes
>Try:
>
> VALUE my_trace_function(int argc, VALUE *argv);

Thanks that works just fine. I've managed to decode 5 of the 6
parameters that can potentially be passed in. I know that sometimes I
don't get all 6 parameters. I'm having a problem decoding the "binding"
parameter. How do I do this? I'd like to be able to determine which
thread and what the local variables are and what the parameters are.

I thought the binding value (argv[4]) was really a struct BLOCK *, where
BLOCK is taken from eval.c

struct BLOCK {
NODE *var;
NODE *body;
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
VALUE klass;
NODE *cref;
int iter;
int vmode;
int flags;
struct RVarmap *dyna_vars;
VALUE orig_thread;
VALUE wrapper;
VALUE block_obj;
struct BLOCK *outer;
struct BLOCK *prev;
};

However if I process argv[4] as a struct BLOCK * I find that the
"orig_thread" value varies wildly, and other values don't seem to make
much sense.

Here is my code, where v is the VALUE from argv[4]

if (v != Qnil)
{
struct BLOCK *blk;

blk = (struct BLOCK *)v;
printf(" binding:%d\n", v);
printf("\tthread:%d\n", blk->orig_thread);
printf("\tself:%d\n", blk->self);
printf("\tframe:%d\n", blk->frame.self);
printf("\tscope:%d\n", blk->scope);
}
else
{
printf(" binding:NIL");
}

How should I be interpreting the binding parameter? I want to avoid
calling eval() and deal with values directly.

Hoping you can help.

Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.d...
RSI Information: http://www.objmedia.d.../rsi.html

ts

11/30/2004 2:09:00 PM

0

>>>>> "S" == Stephen Kellett <snail@objmedia.demon.co.uk> writes:

S> Here is my code, where v is the VALUE from argv[4]

S> if (v != Qnil)
S> {
S> struct BLOCK *blk;

S> blk = (struct BLOCK *)v;

Data_Get_Struct(v, struct BLOCK, blk);


Guy Decoux


Stephen Kellett

11/30/2004 7:52:00 PM

0

In message <200411301408.iAUE8n624627@moulon.inra.fr>, ts
<decoux@moulon.inra.fr> writes
>S> if (v != Qnil)
>S> {
>S> struct BLOCK *blk;
>
>S> blk = (struct BLOCK *)v;
>
> Data_Get_Struct(v, struct BLOCK, blk);

Thanks. Now to decode whats inside the block.

Stephen
--
Stephen Kellett
Object Media Limited http://www.objmedia.d...
RSI Information: http://www.objmedia.d.../rsi.html