拡張パッケージを作成するための、サンプルと手引きは以下のところにあります。
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::* |