1. 包

很多功能存放在一起,定义为一个包,在iTcl(Incr TCL)之后,可以定义一个类,类可以放在一个包里面,包为一个独立的文件,可以为TCL文件,也可以为C/C++语言实现的动态库。

2. 代码结构

.
├── env.sh // 提供了 TCL_PACKAGE_ROOT 环境变量
├── lib
│ ├── init.tcl // tcl 执行时,source 该变量,提供auto_path寻找包的路径
│ ├── libpkg.so // C语言提供的包
│ ├── pkg.c // C代码,编译成libpkg.so
│ ├── pkgIndex.tcl // 包导出方法,该文件生成命令为tclsh环境中执行:pkg_mkIndex -- ./ *.so tools/*.tcl
│ └── tools
│ └── basic.tcl // Tcl提供的包
└── tst
└── test.tcl // 测试代码

3. 各文件内容

3.1. env.sh

#!/bin/bash

export TCL_PACKAGE_ROOT=$(pwd)

3.2. lib/init.tcl

if {[info exists env(TCL_PACKAGE_ROOT)] && (string trim $env(TCL_PACKAGE_ROOT) != "")} {
lappend auto_path $env(TCL_PACKAGE_ROOT)
} else {
puts "Need TCL_PACKAGE_ROOT env."
}

3.3. lib/pkg.c

// gcc -I/path/to/tcl/include -shared -o libpkg.so pkg.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tcl.h" int Pkg_Init(Tcl_Interp *Interp);
int Pkg_Unload(Tcl_Interp *Interp, int flags); int newcmd(int notUsed, Tcl_Interp *interp, int argc, char **argv)
{
if (argc != ) {
Tcl_SetResult(interp, "Usage::newcmd arg1", TCL_VOLATILE);
return TCL_ERROR;
} printf("argv[1] is %s.\n", argv[]);
Tcl_SetResult(interp, "This is my return", TCL_VOLATILE);
return TCL_OK;
} int Pkg_Init(Tcl_Interp *Interp)
{
if (Tcl_PkgProvide(Interp, "pkg", "1.0") == TCL_ERROR) {
return TCL_ERROR;
} Tcl_CreateCommand(Interp, "newcmd", (Tcl_CmdProc *)newcmd, , );
return TCL_OK;
} int Pkg_Unload(Tcl_Interp *Interp, int flags)
{
return TCL_OK;
}

3.4. lib/tools/basic.tcl

package provide Tools 1.0

namespace eval tools {
proc Test {args} {}
} proc tools::Test {args} {
puts "In tools::Test"
}

3.5. tst/test.tcl

#!/usr/bin/env tclsh

source $env(TCL_PACKAGE_ROOT)/lib/init.tcl

package require Tools
package require pkg tools::Test
set retStr [newcmd "hehe"]
puts "==$retStr=="

3.6. lib/pkgIndex.tcl

该文件通过如下方式自动生成:

$ cd lib/
$ tclsh
% pkg_mkIndex -- ./ tools/*.tcl *.so $ cat pkgIndex.tcl
# Tcl package index file, version 1.1
# This file is generated by the "pk_mkIndex" command
# and sourced either when an application starts up or
# by a "package unknown" script. It invokes the
# "package ifneeded" command to set up package-related
# information so that packages will be loaded automatically
# in response to "package require" commands. When this
# script is sourced, the variable $dir must contain the
# full path name of this files's directory.
package ifneeded Tools 1.0 [list source [file join $dir tools/basic.tcl]]
package ifneeded pkg 1.0 [list load [file join $dir libpkg.so]]

4. 测试

$ source env.sh
$ cd tst/
$ chmod +x ./test.tcl
$ ./test.tcl
In tools::Test
argv[] is hehe
==This is my return==

[TimLinux] TCL 自定义包的更多相关文章

  1. 关于iOS和android自定义包的名字

    自定义包名的使用,android的包名和ios的包名都是你的自定义包名!如下以新浪微博SDK自定义包名示例:(官方没的,自己踩过坑,方便后来人吧) 相关技术文档:http://www.apicloud ...

  2. Python 调用自定义包

    创建包 # mkdir -p /python/utils # touch /python/utils/__init__.py # vi /python/utils/Log.pyimport timed ...

  3. Golang自定义包导入

    # 文件Tree project -/bin -/pkg -/src -main.go -/test -test1.go -test2.go main.go package main import ( ...

  4. go语言基础之包和自定义包与main包

    1.包 所有 Go 语言的程序都会组织成若干组文件,每组文件被称为一个包.这样每个包的代码都可以作为很小的复用单元,被其他项目引用. 一个包的源代码保存在一个或多个以.go为文件后缀名的源文件中,通常 ...

  5. Phyton自定义包导入。

    说明:同一个项目下的自定义包. 项目层次: 1:先建好项目Pybasestudty 2:建Python package,包名:pytestpk,__init__.py是建包时自动产生的文件. 3:在该 ...

  6. Go 使用自定义包(package)

    自定义包的分为两种: 1.同目录下的包: 2.不同目录下的包: *经测试,同目录下是不可以用不同包的文件的 同目录下的包: 不同文件中的变量和函数都可以直接访问 不同目录下的包: 1.把要在自定义包外 ...

  7. Go 自定义包引入报错

    配置文件 GO111MODULE=on 设置为on时,go命令行会使用modules,而一点也不会去GOPATH目录下查找.但自定义包在 $GOPATH/github.com/winyh/strrev ...

  8. python-sys模块、导入自定义包

    import问题:https://zhuanlan.zhihu.com/p/69099185 一.sys模块 sys模块是python自带模块,包含了与Python解释器和它的环境有关的函数.利用 i ...

  9. 9.5 自定义包和可见性 go mod

    the-way-to-go_ZH_CN/09.5.md at master · Unknwon/the-way-to-go_ZH_CN https://github.com/Unknwon/the-w ...

随机推荐

  1. 在VMware环境下安装CentOS7

    1. 软件准备: 推荐使用VMware,在这里我使用的是VMware15 映像:可以去官网下载,没有的话也可以在下方链接里下载 链接:https://pan.baidu.com/s/1r_7K-UI0 ...

  2. Elasticsearch生产环境遇到的问题以及解决方案

    Elasticsearch是一个开源的分布式实时搜索与分析引擎,支持云服务.它是基于Apache Lucene搜索引擎的类库创建的,提供了全文搜索能力.多语言支持.专门的查询语言.支持地理位置服务.基 ...

  3. Typings移除Deprecated Warning

    使用TypeScript进行开发中,经常遇到如下的Deprecated Warning.虽然没有实际影响,但看多了,确实挺烦. 要想消除这些Warning,需要以下几个步骤: 步骤一,确认Warnin ...

  4. 在 ASP.NET Core 项目中使用 MediatR 实现中介者模式

    一.前言  最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前 ...

  5. lqb 基础练习 数列特征

    基础练习 数列特征 时间限制:1.0s   内存限制:256.0MB     问题描述 给出n个数,找出这n个数的最大值,最小值,和. 输入格式 第一行为整数n,表示数的个数. 第二行有n个数,为给定 ...

  6. 优秀的github项目学习

    优秀的github项目学习 后期会陆续添加遇到的优秀项目 https://github.com/chaijunkun

  7. 从无到有实现搭建vue+ElementUI+less+ES6的开发环境并进行简单的开发的项目

    项目简介:该项目是基于日常计算宿舍水电煤气费的需求写的,旨在从无到有实现搭建vue+ElementUI+less+ES6的开发环境并进行简单的开发,使用webpack进行代码的编译.压缩和打包,并疏通 ...

  8. 携程Apollo简单入门教程这一篇就够了

    1. Apollo背景 对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境.分集群管理配置,完善的权限.审核机制……   废话不多说,参考官方文档   如果不想看文档, 也没关系, 跟 ...

  9. 设计模式之美学习(九):业务开发常用的基于贫血模型的MVC架构违背OOP吗?

    我们都知道,很多业务系统都是基于 MVC 三层架构来开发的.实际上,更确切点讲,这是一种基于贫血模型的 MVC 三层架构开发模式. 虽然这种开发模式已经成为标准的 Web 项目的开发模式,但它却违反了 ...

  10. 面向对象之classmethod和staticmethod(python内置装饰器)

    对象的绑定方法复习classmethodstaticmethod TOC 对象的绑定方法复习 由对象来调用 会将对象当做第一个参数传入 若对象的绑定方法中还有其他参数,会一并传入 classmetho ...