On Wed, 12 Apr 2000, Vince Darley wrote:

> I'm trying to have more heavy interaction between my Tcl code and Java.  In
> particular I want to be able to pass in a Tcl command to the Java, and have
> it executed at certain intervals, where that command takes a Java object as
> a parameter:
> 
> proc callback {javaobj} {
>     puts stdout [java::info class $javaobj]
> }
> 
> ----
> // TclCallback.java
> 
> ....
> 
> public class TclCallback {
>     public TclCallback(String command, Interp interp) {
>       this.command = command;
>       this.interp = interp;
>     }
>     String command;
>     Interp interp;
> 
>     public void call(MyJavaObject mjo) {
>       try {
>           interp.eval(command + " " + mjo, 0);
>       } catch (TclException te) {
>           Debug.bug("Tcl exception thrown: " +te);
>       }
>     }
> }
> 
> However the callback proc doesn't receive a java-object, but rather a string
> looking like:
>     MyJavaObject@d531bf4b
> 
> So, I guess my 'interp.eval' statement is wrong.  What should it look like?
> 
> thanks,
> 
> Vince.


You have two problems there. You can not just call interp.eval()
from random Java code because it is not thread safe (this is
by design). To make a thread safe call you need to create another
"event" object, add it to the interps event queue, and then
let it get done "later". Like so:

(from src/jacl/tcl/lang/Shell.java)
            ConsoleEvent evt = new ConsoleEvent(interp, sbuf.toString());
            interp.getNotifier().queueEvent(evt, TCL.QUEUE_TAIL);
            evt.sync();

(from src/jacl/tcl/lang/ConsoleEvent.java)
public int
processEvent(
    int flags)          // Same as flags passed to Notifier.doOneEvent.
{
    try {
        interp.eval(script, 0);
    } catch (TclException e) {
        evalException = e;
    } finally {
        evalResult = interp.getResult();
        evalResult.preserve();
    }

    return 1;
}



I will be the first to admit that this is kind of ugly.
I am looking to redesign this part of the interface in the 1.3
tree.


You other problem is that you need to create a "reflect object"
and pass that to your Tcl code.

MyJavaObject mjo = ...

ReflectObject ro = ReflectObject.newInstance(interp, MyJavaObject.class,
mjo);


The reflect object creating also needs to be done in the event
callback, not in the thread unsafe Java callback.

Mo DeJong
Red Hat Inc.

----------------------------------------------------------------
The TclJava mailing list is sponsored by Scriptics Corporation.
To subscribe:    send mail to [EMAIL PROTECTED]  
                 with the word SUBSCRIBE as the subject.
To unsubscribe:  send mail to [EMAIL PROTECTED] 
                 with the word UNSUBSCRIBE as the subject.
To send to the list, send email to '[EMAIL PROTECTED]'. 
An archive is available at http://www.mail-archive.com/tcljava@scriptics.com

Reply via email to