TclBlend 相關文件:
Tcl/Java interoperability with TclBlend 1.4. A new precompiled binary for Window
環境:
Windows XP
MINGW/MSYS
ActiveTcl 8.6.4.1
Java SE 8u65
使用 MINGW/MSYS 參考文章:
Building TclBlend with msys_mingw
下載
Tclblend 1.4.1 以後,加上 Source Forge 的 3 個 patch:
21
allow TclBlend to load Tcl 8.5 into a Java process
22
Compile/Run against Tcl 8.6
24
Patch for TclJava Bug 2866640
然後加上 tclBlend\src\native\javaInterp.c 的一些小改變(for Tcl/Tk 8.6):
if (exception) {
(*env)->DeleteLocalRef(env, exception);
(void) Tcl_GetStringResult(interp);
tPtr->errMsg = (char *)
ckalloc((unsigned) (strlen(Tcl_GetStringResult(interp)) + 1));
//ckalloc((unsigned) (strlen(interp->result) + 1));
//strcpy(tPtr->errMsg, interp->result);
strcpy(tPtr->errMsg, Tcl_GetStringResult(interp));
result = tPtr->errMsg;
}
就 build 出來了。能不能使用則還不知道。
(update) 嘗試使用更加相容其它版本的寫法
#if TCL_MAJOR_VERSION > 8 || \
(TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 5)
ckalloc((unsigned) (strlen(Tcl_GetStringResult(interp)) + 1));
#else
ckalloc((unsigned) (strlen(interp->result) + 1));
#endif
#if TCL_MAJOR_VERSION > 8 || \
(TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION > 5)
strcpy(tPtr->errMsg, Tcl_GetStringResult(interp));
#else
strcpy(tPtr->errMsg, interp->result);
#endif
更新:
無法正確執行範例,會發生 crash 的問題。
使用參考文件所提供的檔案可以成功執行,但是我自己編譯的 tclBlend 如果執行範例會 crash,不知道問題出在哪裡。
更新:
使用 TclBlend, Tcl/Tk 8.5.18 and Thread extension 2.7.2 and JDK 8
(單純的 TclBlend 1.4.1,沒有使用 patch)
測試成功
% package require java
1.4.1
% java::import java.net.InetAddress
% puts "My IP Address is: [ [ java::call InetAddress getLocalHost ] getHostAddress ] "
My IP Address is: 192.168.2.105
更新 2015/12/01:
會是 Tcl 8.5.18 與 Tcl 8.6.4 的版本差異所造成的問題嗎?
更新 2015/12/01:
測試 Tcl 8.6.0,
測試成功
看起來跟 Thread Extension 與 JDK 版本無關
更新 2015/12/01:
測試 Tcl 8.6.1, 結果 crash
TCLBLEND_DEBUG: Interp.evalString()
TCLBLEND_DEBUG: cmd is : ->package provide java 1.4.1<- br="">TCLBLEND_DEBUG: JavaInitBlend returning
TCLBLEND_DEBUG: Tclblend_Init finished
TCLBLEND_DEBUG: JavaInitBlend returned TCL_OK
1.4.1
% java::import java.net.InetAddress
TCLBLEND_DEBUG: JavaCmdProc()
% puts "My IP Address is: [ [ java::call InetAddress getLocalHost ] getHostAddre
ss ] "
TCLBLEND_DEBUG: JavaCmdProc()->
更新:
記錄我對 TclBlend 在 MinGW/MSYS 與 Tcl 8.6.x 編譯的做法(雖然 TclBlend 在 Tcl 8.6.1 及以後的版本沒辦法用)
1. 使用下列的 script 編譯出 Tcl/Tk 8.6.x
(Tcl 與 Tk 的 source code 放在 /src/tcl 與 /src/tk 的目錄下)
#!/bin/sh
mkdir -p /src
mkdir -p /opt/tcl
mkdir -p /build/tcl
mkdir -p /build/tk
[ -e /src/tcl ] && {
cd /build/tcl
/src/tcl/win/configure --prefix=/opt/tcl --enable-threads && make && make install && {
[ -e /src/tk ] && {
cd /build/tk
/src/tk/win/configure --prefix=/opt/tcl --enable-threads --with-tcl=/build/tcl \
&& make && make install
}
}
}
2.Build TclBlend
假設已經下載完 source code package,並且放在 /src/tclBlend
2-1 mkdir /build/tclblend
2-2 cd /build/tclblend
2-3 /src/tclBlend/configure --prefix=/opt/tcl --with-tcl=/build/tcl --with-thread=/build/tcl/pkgs/thread2.7.2/ --with-jdk=/c/JDK8/
2-4 make
2-5 make install
在 2-3 的 thread 要看 Tcl/Tk 8.6.x 當時附帶的 Thread extension 版本。因為 8.6.x 已經會附帶一個 Thread extension 而且在第一個步驟就已經編譯完成,所以不用自己再去下載一個來編譯。
要執行 TclBlend 的時候,使用 jtclsh.bat 或者是 jtclsh 啟動。jtclsh.bat 或者是 jtclsh 都是在設定環境變數,主要有下列幾個可以指定的地方:
set PREFIX=C:/MinGW/msys/1.0/opt/tcl
set EXEC_PREFIX=C:/MinGW/msys/1.0/opt/tcl
set TCLSH=C:/MinGW/msys/1.0/opt/tcl/bin/tclsh86
例如說,如果你複製 C:/MinGW/msys/1.0/opt/tcl 目錄下的檔案到 C:/Tcl/ 下,那麼就需要對這幾個環境變數做相對應的修改。
更新:
TclBlend: Tcl core patch
所以預計在 8.6.6 可以修正 crash 問題,8.6.1 ~ 8.6.5 則需要自己 patch Tcl source code。