Ruby-SWIG question: wrapping function objects with blocks

I am trying to use SWIG to generate Ruby wrapper for a
projet using SWIG.

In out project, there are a lot of functions which
take a function object parameter (Apply)
and call then may call the call method of this
object. I would like to wrap it with a Ruby code
which takes a block and the creates a new apply
object whose call function calls the block.
Is it possible to solve this problem with
SWIG typemaps? I have read the whole documentation,
but I did not see any way to solve this.

In our case, we can assume that the
Apply parameter occures only once in the
parameter list as the last parameter.

Basically, I would need a typemap which tells
that the C++ arugment should not map to any
Ruby argument, but should take its parameter
somewhere else. (Like multivariable typemaps,
which map more parameters to one, here I would
like to map one parameter to no parameter at all.

Does someone have an idea to solve this problem?

Thanks, Christian

Do you want something like this ?

/*

  • within C.
    */
    void my_c_function(HOOK hook) {
    printf(“1\n”);
    hook();
    printf(“3\n”);
    }
···

On Thu, 05 Jun 2003 17:07:03 +0200, Christian Szegedy wrote:

In out project, there are a lot of functions which
take a function object parameter (Apply)
and call then may call the call method of this
object. I would like to wrap it with a Ruby code
which takes a block and the creates a new apply
object whose call function calls the block.

within Ruby.

def my_super_hook
puts “2”
end

If I understand you correct you want to
supply ‘my_super_hook’ to ‘my_c_funtion’. Am I right ?

It is possible… But I don’t know how to exactly do this.

I am working on a tutorial about callback between C++ and Ruby,
which may have your interest.
http://metaeditor.sf.net/embed/


Simon Strandgaard

In out project, there are a lot of functions which
take a function object parameter (Apply)
and call then may call the call method of this
object. I would like to wrap it with a Ruby code
which takes a block and the creates a new apply
object whose call function calls the block.

It is possible… But I don’t know how to exactly do this.

Have you looked in the examples supplyed with SWIG ?

There is a good example of a funcptr.

pwd
/usr/home/neoneye/install/language/SWIG-1.3.19/Examples/ruby/funcptr
ls
Makefile example.h index.html
example.c example.i runme.rb
cat example.h
/* file: example.h */

extern int do_op(int,int, int (*op)(int,int));
extern int add(int,int);
extern int sub(int,int);
extern int mul(int,int);

cat example.c
/* File : example.c */

int do_op(int a, int b, int (*op)(int,int)) {
return (*op)(a,b);
}

int add(int a, int b) {
return a+b;
}

int sub(int a, int b) {
return a-b;
}

int mul(int a, int b) {
return a*b;
}

cat example.i
/* File : example.i */
%module example
%{
#include “example.h”
%}

/* Wrap a function taking a pointer to a function */
extern int do_op(int a, int b, int (*op)(int, int));

/* Now install a bunch of “ops” as constants */
%constant int (*ADD)(int,int) = add;
%constant int (*SUB)(int,int) = sub;
%constant int (*MUL)(int,int) = mul;

cat runme.rb

file: runme.rb

require ‘example’

a = 37
b = 42

Now call our C function with a bunch of callbacks

print “Trying some C callback functions\n”
print " a = #{a}\n"
print " b = #{b}\n"
print " ADD(a,b) = “, Example::do_op(a,b,Example::ADD),”\n"
print " SUB(a,b) = “, Example::do_op(a,b,Example::SUB),”\n"
print " MUL(a,b) = “, Example::do_op(a,b,Example::MUL),”\n"

print “Here is what the C callback function objects look like in Ruby\n”
print " ADD = #{Example::ADD}\n"
print " SUB = #{Example::SUB}\n"
print " MUL = #{Example::MUL}\n"

···

On Thu, 05 Jun 2003 19:04:43 +0200, Simon Strandgaard wrote:

On Thu, 05 Jun 2003 17:07:03 +0200, Christian Szegedy wrote:


Simon Strandgaard

In out project, there are a lot of functions which
take a function object parameter (Apply)
and call then may call the call method of this
object. I would like to wrap it with a Ruby code
which takes a block and the creates a new apply
object whose call function calls the block.

OK… I did it without SWIG… tell me if you can use it ?

ls
CVS/ example.c extconf.rb test.rb
ruby extconf.rb && gmake
creating Makefile
gcc -fPIC -g -O2 -I. -I/home/neoneye/stow/ruby18_r2/lib/ruby/1.8/i386-freebsd5.0 -I/home/neoneye/stow/ruby18_r2/lib/ruby/1.8/i386-freebsd5.0 -I. -c example.c
gcc -shared -rdynamic -Wl,-soname, -L"/home/neoneye/stow/ruby18_r2/lib" -o Example.so example.o -lcrypt -lm -lc
ruby test.rb
before
proc
after
before
yield
after
cat test.rb
require ‘Example’

test_hook = Proc.new do
puts “proc”
end

test(test_hook)

def xtest
p = Proc.new do
yield
end
test(p)
end

xtest do
puts “yield”
end

cat example.c
#include <stdio.h>
#include <ruby.h>

/*
def test(hook); hook.call; end
*/
VALUE wrap_test(VALUE self, VALUE hook) {
printf(“before\n”);
rb_funcall(hook, rb_intern(“call”), 0);
printf(“after\n”);
return Qnil;
}

int Init_Example() {
rb_define_global_function(“test”, wrap_test, 1);
return 0;
}

cat extconf.rb
require ‘mkmf’
create_makefile(“Example”)

···

On Thu, 05 Jun 2003 17:07:03 +0200, Christian Szegedy wrote:


Simon Strandgaard

Simon Strandgaard wrote:

In out project, there are a lot of functions which
take a function object parameter (Apply)
and call then may call the call method of this
object. I would like to wrap it with a Ruby code
which takes a block and the creates a new apply
object whose call function calls the block.

OK… I did it without SWIG… tell me if you can use it ?

Sorry for the long delay, I was on holiday.

Of course, I would have had no problem to do this
without SWIG, but I have a project in which we
wrap everything with SWIG, and we really have a
large number of functions that take exactly one
function object as the last parameter, so I need
an automatic way to wrap them (pereferably with
typemaps).

Best Regards, Christian

···

On Thu, 05 Jun 2003 17:07:03 +0200, Christian Szegedy wrote: