[TimLinux] TCL 自定义包
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 自定义包的更多相关文章
- 关于iOS和android自定义包的名字
自定义包名的使用,android的包名和ios的包名都是你的自定义包名!如下以新浪微博SDK自定义包名示例:(官方没的,自己踩过坑,方便后来人吧) 相关技术文档:http://www.apicloud ...
- Python 调用自定义包
创建包 # mkdir -p /python/utils # touch /python/utils/__init__.py # vi /python/utils/Log.pyimport timed ...
- Golang自定义包导入
# 文件Tree project -/bin -/pkg -/src -main.go -/test -test1.go -test2.go main.go package main import ( ...
- go语言基础之包和自定义包与main包
1.包 所有 Go 语言的程序都会组织成若干组文件,每组文件被称为一个包.这样每个包的代码都可以作为很小的复用单元,被其他项目引用. 一个包的源代码保存在一个或多个以.go为文件后缀名的源文件中,通常 ...
- Phyton自定义包导入。
说明:同一个项目下的自定义包. 项目层次: 1:先建好项目Pybasestudty 2:建Python package,包名:pytestpk,__init__.py是建包时自动产生的文件. 3:在该 ...
- Go 使用自定义包(package)
自定义包的分为两种: 1.同目录下的包: 2.不同目录下的包: *经测试,同目录下是不可以用不同包的文件的 同目录下的包: 不同文件中的变量和函数都可以直接访问 不同目录下的包: 1.把要在自定义包外 ...
- Go 自定义包引入报错
配置文件 GO111MODULE=on 设置为on时,go命令行会使用modules,而一点也不会去GOPATH目录下查找.但自定义包在 $GOPATH/github.com/winyh/strrev ...
- python-sys模块、导入自定义包
import问题:https://zhuanlan.zhihu.com/p/69099185 一.sys模块 sys模块是python自带模块,包含了与Python解释器和它的环境有关的函数.利用 i ...
- 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 ...
随机推荐
- c#数据结构之Array、ArrayList、List、LinkedList对比分析
一.前言: 在c#数据结构中,集合的应用非常广泛,无论是做BS架构还是CS架构开发,都离不开集合的使用,比如我们常见的集合包括:Array.ArrayList.List.LinkedList等.这一些 ...
- JavaScript 运行原理
i{margin-right:4px;margin-top:-0.2em}.like_comment_tips .weui-icon-success{background:transparent ur ...
- (C#)WPF:LinearGradientBrush的使用
在MSDN文档库里可以查到,Rectangle.Fill的类型是Brush.Brush是一个抽象类,凡是以Brush为基类的类都可作为Fill属性的值.Brush的派生类有很多: * SolidCol ...
- nyoj 399-整除个数 (整除)
399-整除个数 内存限制:64MB 时间限制:3000ms 特判: No 通过数:9 提交数:18 难度:1 题目描述: 1.2.3… …n这n(0<n<=1000000000)个数中有 ...
- gin索引优化实例1
GIN(Generalized Inverted Index, 通用倒排索引) 是一个存储对(key, posting list)集合的索引结构,其中key是一个键值,而posting list 是一 ...
- vuejs中的回车事件
@keyup.enter.native="事件名称"
- 20191107-5 beta week 2/2 Scrum立会报告+燃尽图 04
此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9957 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...
- cenos7搭建gitlab
git.github和gitlab的区别 git:是一种版本控制系统,是一个命令,是一种工具 gitlib:是基于实现功能的开发库 github:是一个基于git实现的在线代码仓库软件 gitlib可 ...
- Asp.Net Core下使用swagger生成api文档
目录 一.前期准备 二.配置Swagger 三.参考 .Net Core中有两个集成NSwag的包,分别为Swashbuckle和NSwag.两者的配置大同小异.这里以NSwag为例. 一.前期准备 ...
- Linux -- 进程间通信之管道
管道是 Linux 里的一种文件类型,同时也是 Linux 系统下进程间通信的一种方式 创建一个管道文件有两种方式: Shell 下命令 mkfifo + filename,即创建一个有名管道 ...