From: Oliver Date: 2007-07-18T03:15:02+09:00 Subject: Re: C library extension question Thanks for the suggestions, Ryan and George. I will explore along those lines. Oliver On Jul 16, 10:59 pm, George wrote: > 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.