私には問題ないようです。
Tcl_Eval を実行するために、次の Tcl 拡張機能を作成しました。
#include <tcl.h>
static int
DotestCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
return Tcl_Eval(interp, "source test_namespace.tcl");
}
int DLLEXPORT
Testnamespace_Init(Tcl_Interp *interp)
{
if (Tcl_InitStubs(interp, "8.4", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "dotest", DotestCmd, NULL, NULL);
return Tcl_PkgProvide(interp, "testnamespace", "1.0");
}
Windows上で、私はこれを使用してコンパイルしました:
cl -nologo -W3 -O2 -MD -DNDEBUG -DUSE_TCL_STUBS -I\opt\tcl\include -c test_namespace.c
link -dll -release -out:testnamespace.dll test_namespace.obj \opt\tcl\lib\tclstub85.lib
次に、上記で投稿した内容で test_namespace.tcl ファイルを作成しました。これを実行すると、次のようになります。
C:\opt\tcl\src>tclsh
% load testnamespace.dll Testnamespace
% dotest
Namespace calling ::bob::proc2
%
さらにイントロスペクションを行うと、そのスクリプトから期待されるとおりのことが示されます。
% namespace children ::
::platform ::activestate ::bob ::tcl
% namespace children ::bob
::bob::joe
%
これが本当にうまくいかない場合は、最初に C コードで奇妙なことをしている可能性があります。
アップデート
上記の例は、コンパイル済みパッケージで tcl を拡張するためのものです。どうやらOPはTclを他のアプリケーションに埋め込んでいます。これを行う簡単な例をここに示します。これは、同じコマンドを実行して上記と同じ効果をもたらします。実際には、Tcl をアプリケーションに埋め込む場合、コードは tclAppInit.c ファイルを使用し、独自の Tcl_AppInit 関数を提供する必要があります。通常の Tcl_Main を実行することにより、イベント (ファイルイベントまたはコマンドの後に必要) および対話型シェルを処理するための完全な機能が得られます。その例は、簡単なバージョンに従います。
/* trivial embedding Tcl example */
#include <tcl.h>
#include <locale.h>
int
main(int argc, char *argv[])
{
Tcl_Interp *interp = NULL;
int r = TCL_ERROR;
setlocale(LC_ALL, "C");
interp = Tcl_CreateInterp();
if (interp != NULL) {
Tcl_FindExecutable(argv[0]);
r = Tcl_Eval(interp, "source test_namespace.tcl");
if (TCL_OK == r)
r = Tcl_Eval(interp, "puts [namespace children ::bob]");
Tcl_DeleteInterp(interp);
}
return r;
}
上記の実行:
C:\opt\tcl\src>cl -nologo -W3 -O2 -MD -I\opt\tcl\include test_namesp_embed.c -link -subsystem:console -release -libpath:\opt\tcl\lib tcl85.lib
test_namesp_embed.c
C:\opt\tcl\src>test_namesp_embed.exe test_namespace.tcl
Namespace calling ::bob::proc2
::bob::joe
tclAppInit を使用してストック Tcl インタープリターを拡張する、より優れた埋め込みスキーム:
#include <tcl.h>
#include <locale.h>
#define TCL_LOCAL_APPINIT Custom_AppInit
int
Custom_AppInit(Tcl_Interp *interp)
{
return Tcl_Eval(interp, "source test_namespace.tcl");
}
#include "/opt/tcl/src/tcl.git/win/tclAppInit.c"
これをビルドして実行すると、以前のバージョンと同じ出力が生成されます。
C:\opt\tcl\src>cl -nologo -W3 -O2 -MD -I\opt\tcl\include test_namesp_embed.c -link -subsystem:console -release -libpath:\opt\tcl\lib tcl85.lib
C:\opt\tcl\src>test_namesp_embed.exe
Namespace calling ::bob::proc2
% namespace children ::bob
::bob::joe
% exit