拡張パッケージを作成するための、サンプルと手引きは以下のところにあります。
C/C++言語による拡張パッケージの作成方法は、上記ページに譲るとして、
ここでは、拡張パッケージのnamespace化に関して説明をします。
#include "tclInt.h" #include "tkInt.h" |
Tkを使わない場合は、tkInt.hのインクルードを省略できます。
ここで、パッケージの名前とバージョンを定義します。
パッケージ名とnamespace名は同じでも、違っていても構いません。
#define PACKAGE "Example" /* パッケージの名称 */ #define VERSION "1.0" /* パッケージの版 */ #define NAMESPACE "::example" /* パッケージのNamespace名 */ |
次に、拡張パッケージの初期化でnamespaceを生成します。
/* * 拡張パッケージの初期化 */ int Example_Init( Tcl_Interp *interp ) { Tcl_Namespace *spacePtr; /* Tcl Stubの初期化 */ if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #ifdef USE_TK_STUBS /* Tk Stubの初期化 */ if (Tk_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif // USE_TK_STUBS /* Namespaceの生成 */ spacePtr = Tcl_CreateNamespace(interp, NAMESPACE, (ClientData)0, (Tcl_NamespaceDeleteProc *) NULL); if (spacePtr == NULL) { return TCL_ERROR; } /* コマンドの追加 */ AddCommand(interp, NAMESPACE, "command1", Example_Command1ObjCmd); /* バージョンを返す */ return Tcl_PkgProvide(interp, PACKAGE, VERSION); } |
AddCommand()は、namespaceにコマンドを追加するためのサブルーチンです。
/* * コマンドの追加 */ static Tcl_Command AddCommand( Tcl_Interp *interp, char *nameSpace, char *cmdName, Tcl_ObjCmdProc *cmdProc ) { char *cmdPath; Tcl_DString dString; Tcl_Command cmdToken; Tcl_Namespace *nsPtr; int dontResetList = 0; Tcl_DStringInit(&dString); /* Namespace::Command を作成 */ if (nameSpace != NULL) { Tcl_DStringAppend(&dString, nameSpace, -1); } Tcl_DStringAppend(&dString, "::", -1); Tcl_DStringAppend(&dString, cmdName, -1); cmdPath = Tcl_DStringValue(&dString); /* 登録のチェック */ cmdToken = Tcl_FindCommand(interp, cmdPath, (Tcl_Namespace *)NULL, 0); if (cmdToken != NULL) { Tcl_DStringFree(&dString); return cmdToken; } /* コマンドの登録 */ cmdToken = Tcl_CreateObjCommand(interp, cmdPath, cmdProc, NULL, NULL); Tcl_DStringFree(&dString); /* Namespaceのポインタ取得 */ nsPtr = Tcl_FindNamespace(interp, nameSpace, (Tcl_Namespace *)NULL, TCL_LEAVE_ERR_MSG); if (nsPtr == NULL) { return NULL; } /* コマンドをエクスポート */ if (Tcl_Export(interp, nsPtr, cmdName, dontResetList) != TCL_OK) { return NULL; } return cmdToken; } |
これでnamespace化は完了です。
package require Example 1.0 namespace import example::* |