From: George Date: 2007-07-17T11:59:52+09:00 Subject: Re: C library extension question On 7/17/07, Oliver wrote: > > Now, from a wrapper stand point of view, I was hoping that the user- > provided function func_a(), func_b() etc. can be done by ruby as well > - it will be very awkward for a user to use partial c, partial ruby > for the same library. I don't see why rb_funcall() can help in this > case - in a sense, this case calls for a way to map ruby function into > C function, for the sake of using the C library call. Hi Oliver, Does the library let you specify an argument to pass to these callbacks when you register them somehow? If so, I'd probably define the callbacks as Procs (or anything with #call) on the ruby side, and in the C side, register the same function, say run_command(VALUE proc) for all the commands, passing the Proc as an argument. run_command() would just use rb_funcall to call the proc's #call. If not, and you do indeed have to register distinct C functions for each command, two ideas come to mind: 1. Have a hard limit on the number of commands, and define C functions func1, func2, ... funcN to call the n-th one. 2. Use RubyInline to dynamically define each C function, load it as a shared library, and add it to your struct (as Ryan just mentioned). As for the interface on the ruby side, a few options come to mind. The more direct translation of the C API: command1 = lambda{|*args| ... } command2 = lambda{|*args| ... } ... register(command1, command2, ...) (You could have #register have symbols denote method calls on Object too, but I think procs would feel the most natural.) Define by blocks on a method: add_command{|*args| ... } add_command{|*args| ... } ... register_commands Register by block: register_commands do |c| c.add{|*args| ... } c.add{|*args| ... } end Hope this gives you some ideas, George.