原文:
12.11. How do I call Tcl code from perl/Tk?
Assuming that you have a pressing need to call Tcl from perl/Tk then one "official way" to so would be via the ->send() and the ->Receive() methods.
It is also worth noting that you can still have access to a complete Tcl script from perl via the perl system, or `` (backtick), or even exec mechanisms. Just be careful with I/O waits and return values if you try one of these approaches. Further suggestions may be found in the various perlipc files at: ftp://ftp.perl.com/perl/info/everything_to_know/
A more satisfactory Tcl/Tk-wish-like behavior can be embedded in perl by making appropriate modifications to Dov Grobgeld's perl script that uses sockets for perl<->wish communication: #!/usr/local/bin/perl###################################################################### An example of calling wish as a subshell under Perl and# interactively communicating with it through sockets.## The script is directly based on Gustaf Neumann's perlwafe script.## Dov Grobgeld dov@menora.weizmann.ac.il# 1993-05-17##################################################################### $wishbin = "/usr/local/bin/wish"; die "socketpair unsuccessful: $!!\n" unless socketpair(W0,WISH,1,1,0); if ($pid=fork) { select(WISH); $| = 1; select(STDOUT); # Create some TCL procedures print WISH 'proc echo {s} {puts stdout $s; flush stdout}',"\n"; # Create the widgets print WISH <<TCL; # This is a comment "inside" wish frame .f -relief raised -border 1 -bg green pack append . .f {top fill expand} button .f.button-pressme -text "Press me" -command { echo "That's nice." } button .f.button-quit -text quit -command { echo "quit" } pack append .f .f.button-pressme {top fill expand} \\ .f.button-quit {top expand}TCL # Here is the main loop which receives and sends commands # to wish. while (<WISH>) { chop; print "Wish sais: <$_>\n"; if (/^quit/) { print WISH "destroy .\n"; last; } } wait; } elsif (defined $pid) { open(STDOUT, ">&W0"); open(STDIN, ">&W0"); close(W0); select(STDOUT); $| = 1; exec "$wishbin --"; } else { die "fork error: $!\n"; }
Ilya Zakharevich mailto:ilya@math.ohio-state.edu has a "ptcl.h" header file for the construction of tcl bindings from pTk (there are limitations to this approach). It was posted to the mailing list archive at: http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.11/0057.html
If you absolutely must pass large amounts of pre-parsed data between Tcl and perl then perhaps you should look into Malcolm Beattie's Tcl/Tk extensions to Perl instead. Those modules are distrubuted at CPAN sites. As mentioned above running Tcl/Tk/perl is incompatible with running perl/Tk.
译文:
12.11 如何在Perl/Tk脚本中调用Tcl的代码?
假设你迫切的需要在Perl/Tk的脚本中使用某些特殊的Tcl功能(而这些功能暂时还没有被“正式”的引入到Perl/Tk中),则你需要使用->send()和->Receive()方法。
值得一提的是,对于完整的Tcl脚本,我们还可以通过使用system或` `(反引号),或甚至是exec等机制。但是你必须注意诸如I/O等待和返回值等问题。关于perlipc的文档(或手册)中包含更进一步的讨论:
ftp://ftp.perl.com/perl/info/everything_to_know/
另外,下面由Dov Grobgeld提供的Perl脚本使用socket在Perl和wish之间进行通讯。因此,这也同样提供了我们一种把Tcl/Tk(wish)的代码嵌入Perl脚本中的方法——只要适当的修改这个脚本就可以了!(译者注:wish是Unix/Linux系统自带的Tcl/Tk的shell,所以下面的脚本可能无法在windows下运行……)
#!/usr/local/bin/perl
#####################################################################
# An example of calling wish as a subshell under Perl and
# interactively communicating with it through sockets.
#
# The script is directly based on Gustaf Neumann's perlwafe script.
#
# Dov Grobgeld dov@menora.weizmann.ac.il
# 1993-05-17
#####################################################################
$wishbin = "/usr/local/bin/wish";
die "socketpair unsuccessful: $!!\n" unless socketpair(W0,WISH,1,1,0);
if ($pid=fork) {
select(WISH); $| = 1;
select(STDOUT);
# Create some TCL procedures
print WISH 'proc echo {s} {puts stdout $s; flush stdout}',"\n";
# Create the widgets
print WISH <<TCL;
# This is a comment "inside" wish
frame .f -relief raised -border 1 -bg green
pack append . .f {top fill expand}
button .f.button-pressme -text "Press me" -command {
echo "That's nice."
}
button .f.button-quit -text quit -command {
echo "quit"
}
pack append .f .f.button-pressme {top fill expand} \.f.button-quit {top expand}
TCL
# Here is the main loop which receives and sends commands
# to wish.
while (<WISH>) {
chop;
print "Wish sais: <$_>\n";
if (/^quit/) { print WISH "destroy .\n"; last; }
}
wait;
} elsif (defined $pid) {
open(STDOUT, ">&W0");
open(STDIN, ">&W0");
close(W0);
select(STDOUT); $| = 1;
exec "$wishbin --";
} else {
die "fork error: $!\n";
}
Ilya Zakharevich为从pTk中构建Tcl绑定而制作了一个名为“ptcl.h”的头文件。这个文件被贴在了一个邮件列表中:
http://sun20.ccd.bnl.gov/~ptk/archive/ptk.1995.11/0057.html
如果你实在需要在Perl和Tcl之间传递大量的数据,那么你也许应该先看一看Malcolm Beattie为Perl做的一些Tcl/Tk的扩展模块,这些模块都发布在CPAN的站点上。
最后说一下,上面说使用的Tcl/Tk/perl的方法应该是非常情况下,不得以而采用的方案,因为这样的用法对Perl/Tk而言是不稳定的。