On Thu, Jul 31, 2003 at 08:19:07PM +0900, Tim Sutherland wrote:
> > Did you solve the problem w/ threads (does it happen at all w/
> > C# ?)
> > 
> > In my case, Java threads are spawned as "real" (native) threads, so if
> > any of them tries to call Ruby code the thing will bomb (Ruby not being
> > thread safe).
> 
> No, I did not solve the thread problem. In addition to the problem with
> dotnet threads, if you are using Ruby threads then a call to a dotnet
> object can block, preventing other Ruby threads from running.

Yes, there's no easy way to work around the latter until we get Rite.

> > A few more questions:
> >  * are you doing proper method dispatching on method overload?
> >    This can be tricky if you perform automatic Ruby -> C#/Java type
> >    conversions as there might be several matching methods
> 
> I only do a few automatic type conversions, e.g. strings. What problems
> are you thinking of?
> 
> The dotnet method I am using is Type#InvokeMember which claims to choose
> the best method.

I think it's easier to call C# code from C than using JNI to run Java
code... In my case, it's up to me to find the correct method, with the
appropriate signature, before dispatching. This can be quite slow as I
have to use reflection at run time quite heavily: get the list of
methods of an object, get the return type and parameter types of each
method, check passed arguments and perform type conversions (just String -> 
java.lang.String, Object -> boolean and Numeric -> one of char, byte,
short, int, long, float, double)

> >  * do you have metaclasses for static methods or such? Do you think it's
> >  sensible to provide them? (I did that in rjni)
> 
> I'm not sure what you mean.
> 
> You can do
> 	klass = DotNet.SomeNamespace.SomeClass
> 	klass.SomeStaticMethod("Hello")
> 
> 	inst = klass.new(1, 2, 3)
> 	inst.SomeStaticMethod("World")
> 	inst.SomeInstanceMethod(42)

When using JNI, I have to implement it myself if I intent to call
static methods (which are like singleton methods in Ruby) on some class,
creating a proxy object to delegate the calls, etc.

> Ben Schroeder and John R. Pierce have written a similar library which
> uses sockets. It implements an interesting feature (not yet available in
> my library) which is to turn Ruby blocks into C# Delegates (these are
> like function pointers.)
> 
> Ben offers the following example:
> 
>      dotNet.loadLibrary('System.Windows.Forms')
> 
>      button = dotNet.Button.new
> 
>      button.click.add do |sender, args|
>              puts "Button clicked!"
>      end
> 
>      button.performClick # -> prints <<Button clicked!>>

I can do that in my code (implement Java interfaces in Ruby and pass
them to Java code) but this won't work with GUIs since I face again the
threading issue. That's why I was thinking of using sockets, too, but
Robert Klemme had an interesting idea I might be able to implement.

What speed are you getting with rubydotnet? I suspect it will be much
faster than RJNI since C#'s C interface seems to be much more sensible
than JNI.

In my case, when using the low-level JNI methods from Ruby I get around
200000 method calls/s on a K7 1.3GHz. 
When using the "automagic reflection" (that is the higher-level part
similar to rubydotnet), I get some 20000 method calls/s. But I can
easily make it much faster since 
 * it's using the wrapped JNI calls from Ruby instead of the C JNI API
   directly
 * it's implemented in Ruby at the moment (this means type checking,
   conversions, etc) using the JNI binding

Once I fix the Ruby code I can reimplement everything in C and I expect
to approach 500000 method calls/s or so.

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

The state of some commercial Un*x is more unsecure than any Linux box
without a root password...
	-- Bernd Eckenfels